过程是这样的,在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 e664630
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.
不废话,直接查看该内存是什么:
0x0E664630 0e 00 0f 00 59 03 10 04 aa aa cd ab 00 10 72 85 38 00
看不出什么,往上再看看:
0x0E66460C 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
开始各种调试,几乎用遍了<
普通页堆通过填充模式检测堆块破坏,需要再发生堆破坏之后再调用一次堆管理器.
完全页堆除了特定的填充模式外,它还为每个堆块增加了防护页,防护页是一个页不可访问的内存,它被放置在堆块的起始位置和结束位置上.防止堆块上下溢出.
我靠,直接pageheap /enable xx.exe /full 设置完全页堆模式.重新运行程序.
瞬间程序崩掉,这个激动呀.还是第一次看见程序崩掉那么激动,查看崩溃的代码:
原来是把一个类指针强转为另一个子类的指针,调用了子类的一个函数,但是该类不存在这个函数.同时这个子类函数里面做了一次bool变量赋值,结果这个值就写到了堆地址里面去了.
总结
以后遇到类似问题,直接pageheap full 全开.