先说一下问题,如何让下面程序(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块的边界处,这样一旦越界访问,程序就自然报错了。