落鹤生:与此相关的另一篇文章:http://www.rosoo.net/a/201111/15296.html,这里说明的更加详细,建议参考一下。 过程是这样的,在vc debug的过程中,突然弹出了一个assert窗口: Windows has triggered a breakpoint in cs.exe. This may be due to a corruption of the heap, which indicates a bug in cs.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while cs.exe has focus. 查看output输出: Heap missing last entry in committed range near e6****630 Windows has triggered a breakpoint in cs.exe. This may be due to a corruption of the heap, which indicates a bug in cs.exe or any of the DLLs it has loaded. 不废话,直接查看该内存是什么: 0×0E6****630 0e 00 0f 00 59 03 10 04 aa aa cd ab 00 10 72 85 38 00 看不出什么,往上再看看: 0×0E6****60C 07 e2 04 00 a8 01 66 0e 01 00 cd cd fd fd fd fd…. 看来这就是块堆内存,实在看不出什么,决定暂时忽略. 过了几天,该错误没有再出现过. 但就在交付程序前一天测试中,又出现了这个错误.看来一颗定时炸弹是埋藏在了程序中.必须找出来,否则后果很严重. 首先要做的就是要重现这个问题,如果每次碰巧遇到这个问题的话,实在无从下手.从症状来看,是个典型的Heap Corrupt.所以先使用工具:pageheap,以做到能够百分百重现那个堆破坏. page heap工具启用的两种方法:Full-page heap和Normal page heap 我先使用了Normal page heap 命令为pageheap /enable xx.exe /normal 然后通过windbg设置符号表:x:\symbols_folder;srv*x:\symbols_folder*http://msdl.microsoft.com/download/symbols 开始各种调试,几乎用遍了<>这本书中指导的各种命令,(调试过程省略2000字)未果.几乎崩溃时,突然看到书上的这么一段话: 普通页堆通过填充模式检测堆块破坏,需要再发生堆破坏之后再调用一次堆管理器. 完全页堆除了特定的填充模式外,它还为每个堆块增加了防护页,防护页是一个页不可访问的内存,它被放置在堆块的起始位置和结束位置上.防止堆块上下溢出. 我靠,直接pageheap /enable xx.exe /full 设置完全页堆模式.重新运行程序. 瞬间程序崩掉,这个激动呀.还是第一次看见程序崩掉那么激动,查看崩溃的代码: 原来是把一个类指针强转为另一个子类的指针,调用了子类的一个函数,但是该类不存在这个函数.同时这个子类函数里面做了一次bool变量赋值,结果这个值就写到了堆地址里面去了. 总结 以后遇到类似问题,直接pageheap full 全开. (jiejie) |