先說一下問題,如何讓下面程序(release版本)能立即報(bào)出異常,程序出錯(cuò)?默認(rèn)情況很大可能是不crash的
int _tmain(int argc, _TCHAR* argv[])
{
char *p=new char[10];
for(int i=0;i<10;++i) p[i]=i;
p[10]=10;
return 0;
}
眾所周知,heap問題一般比較難于處理,因?yàn)槌绦驁?bào)錯(cuò)的地方也許不是問題的源頭,最好的辦法是在第一時(shí)間讓對(duì)堆的非法操作報(bào)錯(cuò),這樣就能找到根本原因。
Gflags是隨著微軟Debugging tools for windows一起發(fā)布的工具。
使用Gflags就能讓系統(tǒng)對(duì)heap的分配,訪問做一些檢查,盡早的發(fā)現(xiàn)問題。
Gflags的具體用法請參考微軟的幫助文檔,就不羅嗦了
Run:
gflags -p /enable test.exe /full /unaligned
這時(shí)候運(yùn)行起來后就會(huì)crash,程序會(huì)break在p[10]=10;這一句上
那么gflags是如何做到這一點(diǎn)的呢
我們在windbg中去觀察一下,不難發(fā)現(xiàn)原因
0:000> g
(da8.f88): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=01766ff6 ebx=00000000 ecx=0000000a edx=016c5000 esi=00000001 edi=00403378
eip=0040101f esp=0012ff80 ebp=0012ffc0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
bbb!wmain+0x1f:
0040101f c6400a0a mov byte ptr [eax+0Ah],0Ah ds:0023:01767000=??
0:000> !address eax
016c0000 : 01766000 - 00001000
Type 00020000 MEM_PRIVATE
Protect 00000004
PAGE_READWRITE State 00001000 MEM_COMMIT
Usage RegionUsagePageHeap
Handle 016c1000
0:000> !address eax+0a
016c0000 : 01767000 - 00059000
Type 00020000 MEM_PRIVATE
Protect 00000001
PAGE_NOACCESS State 00001000 MEM_COMMIT
Usage RegionUsagePageHeap
Handle 016c1000
這時(shí)候我們通過new得到的內(nèi)存就剛好在heap塊的邊界處,這樣一旦越界訪問,程序就自然報(bào)錯(cuò)了。