If you come across another thread overwriting memory of the crashing thread , it is useful to use gflags ( GFlags and PageHeap ). Instead of telling you a few lines that were executed before the failure, it will tell you exactly where your algorithm overwrites the correctly allocated memory block.
First you activate this type of check:
gflags /p /enable your_app.exe /full or
gflags /p /enable your_app.exe /full /backwards
Make sure you activate correctly
gflags /p
run the application and collect the dump files
and then turn off validation with gflags:
gflags /p /disable your_app.exe
<h / "> Update 1
It does not immediately detect problems like *p = 0; where p is an invalid pointer
At least some problems have been discovered.
For example:
#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; }
When I start with gflags turned on, I get a dump file, and the problem is correctly identified:
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: }
<h / "> Update 2
Another example from @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: }
Unfortunately, the / unaligned option may cause the program to not work properly ( How to use the Pageheap.exe file ):
Some programs make assumptions about 8-byte alignment, and they stop working correctly with the / unaligned option. Microsoft Internet Explorer is one such program.