今天调试一个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:内存.
小编点评:win10初音未来鼠标指针主题包是.
下载小编点评:Lily启动管理附破解工具包是一款管理工.
下载小编点评:还在为你那脆弱到不堪一击的密码担心.
下载小编点评:护密文件夹加密精灵是一款可以帮你快速给.
下载小编点评:追影文件夹加密锁是一款适用win10.
下载小编点评:NoteSV(隐私管理工具),No.
下载小编点评:这款必应输入法皮肤编辑器是必应官方发布的输.
下载小编点评:Win32是个多任务抢占式操作系统,每.
下载小编点评:AHK屏保是以翻页时钟的形式所存在的.
下载小编点评:当我们的系统运行了一些时间后,系统就会自然的占.
下载小编点评:本工具测试成绩不代表CPU整体性能。很.
下载小编点评:今天调试一个bug,用pageheap.
下载小编点评:软件介绍要是这些电子邮件可以汇集到Gm.
下载ClockAlign(ClockAlign电脑时间显示工具)V1.1 Beta 5下载
桌面工具 / 266.53MB / 2021-4-16 / Win8,Win7,WinXP / 简体中文 / 免费软件 下载Easy-PrintScreen V1.3.0.1下载
图像管理 / 366.50MB / 2016-5-24 / Win8,Win7,WinXP / 简体中文 / 免费软件 下载CrossEyes V1.0.0下载
文字处理 / 718.98MB / 2017-9-24 / Win8,Win7,WinXP / 英文 / 免费软件 下载图片保护狗V6.3.0.0下载
图像管理 / 271.41MB / 2015-3-4 / Win8,Win7,WinXP / 简体中文 / 商业软件 下载Quick HDR V1.0.0.1下载
图像管理 / 17.18MB / 2018-9-23 / Win8,Win7,WinXP / 英文 / 商业软件 下载图睿图片统计V1.0.0.0下载
图像管理 / 280.92MB / 2022-4-27 / Win8,Win7,WinXP / 简体中文 / 免费软件 下载MySecretFolder(文件夹加密软件)V5.3下载
加密解密 / 733.72MB / 2021-9-4 / Win8,Win7,WinXP / 英文 / 共享软件 下载人生日历2014(人生日历下载) 3.3.35.387下载
桌面工具 / 992.54MB / 2023-2-6 / Win8,Win7,Vista,Win2003,WinXP / 简体中文 / 免费软件 下载尚书七号OCR文字识别软件V1.0免费版下载
文字处理 / 121.27MB / 2014-8-3 / Win8,Win7,WinXP / 简体中文 / 免费软件 下载闪念邮件V1.0.1.3免费版下载
邮件处理 / 136.15MB / 2015-11-16 / Win8,Win7,WinXP / 简体中文 / 免费软件 下载联想护眼卫士下载-联想护眼卫士 v2.6.60.5081
桌面工具 / 656.29MB / 2016-5-24 / WinAll / 简体中文 / 免费软件 下载Chameleon下载-Chameleon v1.6
桌面工具 / 921.72MB / 2020-3-5 / WinAll / 英文 / 免费软件 下载USEO高级AI伪原创工具下载-USEO高级AI伪原创工具 v1.0 免费版
文字处理 / 729.11MB / 2012-8-23 / WinAll / 简体中文 / 免费软件 下载