如果您遇到使用gflags(GFlags 和 PageHeapanother thread overwriting memory of the crashing thread
)很有用的情况。它不会告诉您崩溃前已执行的几行代码,而是会准确地告诉您算法覆盖正确分配的内存块的位置。
您首先激活此类检查:
gflags /p /enable your_app.exe /full
或者
gflags /p /enable your_app.exe /full /backwards
检查您是否已正确激活
gflags /p
运行您的应用程序并收集转储文件
然后使用 gflags 禁用检查:
gflags /p /disable your_app.exe
更新 1
It does not immediately detect problems like *p = 0; where p is an invalid pointer
至少检测到一些问题。
例如:
#include <stdio.h>
int main(int argc, char *argv[])
{
int *p = new int;
printf("1) p=%p\n",p);
*p = 1;
delete p;
printf("2) p=%p\n",p);
*p = 2;
printf("Done\n");
return 0;
}
当我在启用 gflags 的情况下运行时,我得到一个转储文件并且问题被正确识别:
STACK_TEXT:
0018ff44 00401215 00000001 03e5dfb8 03dfdf48 mem_alloc_3!main+0x5b [c:\src\tests\test.cpp\mem_alloc\mem_alloc\mem_alloc.3.cpp @ 11]
0018ff88 75f8339a 7efde000 0018ffd4 77bb9ef2 mem_alloc_3!__tmainCRTStartup+0x10f [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 586]
0018ff94 77bb9ef2 7efde000 2558d82c 00000000 kernel32!BaseThreadInitThunk+0xe
0018ffd4 77bb9ec5 004013bc 7efde000 00000000 ntdll!__RtlUserThreadStart+0x70
0018ffec 00000000 004013bc 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND: ~0s; .ecxr ; kb
FAULTING_SOURCE_CODE:
7: printf("1) p=%p\n",p);
8: *p = 1;
9: delete p;
10: printf("2) p=%p\n",p);
> 11: *p = 2;
12: printf("Done\n");
13: return 0;
14:
15: }
更新 2
@fmunkert 的另一个例子:
#include <stdio.h>
int main()
{
int *p = new int;
printf("1) p=%p\n",p);
*p = 1;
p++;
printf("2) p=%p\n",p);
*p = 2; // <==== Illegal memory access
printf("Done\n");
return 0;
}
gflags /p /enable mem_alloc.3.exe /full /unaligned
STACK_TEXT:
0018ff44 00401205 00000001 0505ffbe 04ffdf44 mem_alloc_3!main+0x52 [c:\src\tests\test.cpp\mem_alloc\mem_alloc\mem_alloc.3.cpp @ 12]
0018ff88 75f8339a 7efde000 0018ffd4 77bb9ef2 mem_alloc_3!__tmainCRTStartup+0x10f [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 586]
0018ff94 77bb9ef2 7efde000 2577c47c 00000000 kernel32!BaseThreadInitThunk+0xe
0018ffd4 77bb9ec5 004013ac 7efde000 00000000 ntdll!__RtlUserThreadStart+0x70
0018ffec 00000000 004013ac 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND: ~0s; .ecxr ; kb
FAULTING_SOURCE_CODE:
8: printf("1) p=%p\n",p);
9: *p = 1;
10: p++;
11: printf("2) p=%p\n",p);
> 12: *p = 2; // <==== Illegal memory access
13: printf("Done\n");
14: return 0;
15:
16: }
不幸的是/unaligned选项可能会导致程序无法正常运行(如何使用 Pageheap.exe):
一些程序假设 8 字节对齐,并且它们停止使用 /unaligned 参数正常工作。Microsoft Internet Explorer 就是这样一种程序。