先說一下問題,如何讓下面程序(release版本)能立即報出異常,程序出錯?默認情況很大可能是不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問題一般比較難于處理,因為程序報錯的地方也許不是問題的源頭,最好的辦法是在第一時間讓對堆的非法操作報錯,這樣就能找到根本原因。
Gflags是隨著微軟Debugging tools for windows一起發布的工具。
使用Gflags就能讓系統對heap的分配,訪問做一些檢查,盡早的發現問題。
Gflags的具體用法請參考微軟的幫助文檔,就不羅嗦了
Run:
gflags -p /enable test.exe /full /unaligned
這時候運行起來后就會crash,程序會break在p[10]=10;這一句上
那么gflags是如何做到這一點的呢
我們在windbg中去觀察一下,不難發現原因
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
這時候我們通過new得到的內存就剛好在heap塊的邊界處,這樣一旦越界訪問,程序就自然報錯了。