今天调试一个bug,用pageheap解决,在此记录一下。
bug症状如下:
1:不确定性崩溃,用vs调试启动每次崩溃地点都在crt分配或者释放堆的位置2:崩溃时vs看到的调用栈可能不同3:output输出HEAP:FreeHeapblock388c58modifiedat388c88afteritwasfreed
问题分析:
根据vs的输出,确定问题是在一块堆上分配的内存在释放后被改写了。由于CRT只能在下次做堆操作检查时才会暴露出问题,所以程序崩溃的调用栈是不确定的。折腾了2个小时后,启用pageheap缩小了程序出错到崩溃之间的距离,解决了问题。过程如下:1:启动pageheappageheap/enablemybug.exe0x012:调试启动mybug.exe现在程序崩溃的调用栈每次都相同,并且都在相同的线程中,根据调用栈信息很轻松的锁定了bug。
由于上面的例子过于复杂,下面写了一些小程序分析了pageheap的原理
char*buffer=newchar;???????//1buffer=0;?????????????????????//2delete[]buffer;???????????????????//3
这是一个很简单的堆内存越界的例子,在未启动pageheap的情况下,我们来看看buffer的内存情况:buffer=0x00388C80第一行执行后,buffer的内存
0x00388C80?cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd??................0x00388C90?cdcdcdfdfdfdfdababababababababfe?................
简单说明一下,调试模式下堆上未初始化的内存为cd,并且在内存结束处有4个fd的边界,用于debug模式下crt做内存检查,执行第2行之后,buffer的内存为
0x00388C80?cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd?................0x00388C90?cdcdcd00fdfdfdababababababababfe?................
可以看到4个fd的内存边界中第一个fd被破坏了。但这个时候程序并没有崩溃,继续执行第3行,程序崩溃,提示堆错误,可以看到,如果第2行和第3行之间有很长的代码逻辑,那么也只能在第3行执行之后程序才会崩溃。这给调式程序带来了极大的不便。如果第2行改为:buffer=0程序同样不会崩溃如果启用了pageheap,再来看看在debug模式下buffer的内存分配情况:第一行分配内存后,buffer的内存情况:
0x01675FE8?cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd?................0x01675FF8?cdcdcdfdfdfdfdd0?????????????????................
可以看到,和上面一样,在内存结束加上了4个fd的边界,d0是用于填补4字节对齐,注意buffer后面的地址(第一个??)为0x01675FF8+8=0x01676000,这是一个4k对齐的PAGE_NOACCESS页面,这个时候我们执行第2行代码buffer=0;同样不会崩溃,即使是修改buffer的值(4个fd边界和1个对齐d0),和未启动pageheap一样,程序都只会在执行第3行的时候崩溃。如果修改buffer则程序会崩溃。
通过这个例子,可以得出一个结论:启用pageheap后,堆内存分配在页面的末尾,后面紧跟了一个4k的PAGE_NOACCESS属性的页面,这种情况下,启用pageheap的好处是能在一定程度上检查内存越界。
再来看一个例子
char*buffer=newchar;?//1delete[]buffer;?????????????//2buffer=1;????????????????//3
这个例子演示了操作delete释放后的内存,在未启动pageheap的情况下,程序不会崩溃,原因同上一个例子,启用pageheap后,buffer内存为:第一行执行后:
0x01675FE8?cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd?................0x01675FF8?cdcdcdcdfdfdfdfd?????????????????................
第2行执行后:
0x01675FE8??????????????????????????????????................0x01675FF8??????????????????????????????????................
可以看到,启用pageheap后delete内存,分配该内存的整个页面都被设置为PAGE_NOACCESS属性,这样操作delete后的任何内存程序马上就会崩溃。
结论2:启用pageheap很容易检查操作delete后的内存的错误(包括2次delete)
总结:1:启用pageheap后,系统的堆管理器会把内存分配到4k页面的末尾(注意需要4字节对齐,debug模式下还存在边界检查的4字节fd)2:紧随着的下一个页面被设置为PAGE_NOACCESS属性3:启用pageheap后,释放内存把整个页面设置为PAGE_NOACCESS属性4:内存越界和非法操作依靠非法访问PAGE_NOACCESS属性的页面暴露问题5:由于每块内存都至少需要2个页面(1个页面分配,1个页面PAGE_NOACCESS),在内存消耗较大的环境下会占用极大的内存资源。6:把pageheap和crt的堆检查函数结合起来,能够更好的暴露堆相关bug
ps.pageheap的作用是在注册表位置HKLM/SOFTWARE/Microsoft/WindowsNT/CurrentVersion/ImageFileExecutionOptions下生成一个项
Tags:内存.
小编点评:AgisoftMetashapeProf.
下载小编点评:华宝证券独立交易软件是华宝证券致富版是华宝.
下载小编点评:阿里云是目前国内最大的数据云、CDN加速.
下载小编点评:河马webshell查杀是专门针对w.
下载小编点评:圈圈99名片赞软件是2016年最新版名片刷.
下载小编点评:??intelprocessordiag.
下载小编点评:机甲兵团17雷霆计划v1.0a【攻略】.
下载小编点评:最强忍者集合v1.12今天更新啦!新版本.
下载小编点评:软件介绍TinCam是一个强力的webcam程.
下载小编点评:软件介绍免费进程分析软件。而且是不.
下载小编点评:软件介绍诛仙主角碧瑶的系统主题模版。以当前.
下载小编点评:软件介绍大洋销售管理系统是一款通用性极强的商业、.
下载小编点评:软件介绍AdvancedOnion.
下载MuMu手游助手下载-MuMu手游助手 v3.3.17
好医师诊所管家V6.2.3.40507免费版下载
Static Windows Mail Backup下载-邮件备份工具 v2.9
甘蔗泡泡龙V1.0下载版下载
花雾精灵2(暂未上线)
灵妖飞仙九游客户端下载-灵妖飞仙九游版下载v5.6.0 安卓版
笃炅柳ps模拟器软件下载-笃炅柳ps模拟器app下载v1.0.4 安卓版
方块功夫官方版下载-方块功夫游戏下载v1 安卓版
忍者战争游戏下载-忍者战争手机版下载v1.5.7 安卓版
make11安卓下载-make11游戏下载v1.0.0 安卓版
西游记口袋版h5手游下载-西游记口袋版h5下载v1.1.0.00590020 安卓版
布娃娃对战大师模拟沙盒对战下载-布娃娃对战大师游戏下载v300.1.0.3018 安卓版
sweet sugar match游戏-sweet sugar match官方版(暂未上线)v1.0 安卓版