Reputation: 263
I would like to create process dump file at the moment when access violation that will not be handled occurred.
Currently, I have registered mine, unhandled exception callback with:
SetUnhandledExceptionFilter(CustomUnhandledExceptionFilter);
CustomUnhandledExceptionFilter creates dump file and prints call stack.
But this approach has one flaw - it is done when AV has already happened, AV exception is thrown and has not been handled by thread it happened in. Unhandled exception callback is called when exception is about to leave thread scope and dump created at this point has no local variables of function that exception occurred since stack pointer is lost.
Is there an way to over come this? I would like to take a look at stack of thread that got AV at the moment AV happened.
Upvotes: 3
Views: 4196
Reputation: 2180
VS
#include "stdafx.h"
#include <windows.h>
#include <dbghelp.h>
LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
{
HANDLE hFile = CreateFile(
L"proc.dmp",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
MINIDUMP_EXCEPTION_INFORMATION mei;
mei.ThreadId = GetCurrentThreadId();
mei.ClientPointers = TRUE;
mei.ExceptionPointers = ExceptionInfo;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&mei,
NULL,
NULL);
return EXCEPTION_EXECUTE_HANDLER;
}
int _tmain(int argc, _TCHAR* argv[])
{
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
int* p = NULL;
*p = 1;
return 0;
}
WinDbg
Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [D:\Documents\Visual Studio 2012\Projects\Test\Debug\proc.dmp]
User Mini Dump File: Only registers, stack and portions of memory are available
Symbol search path is: SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 7 Version 7600 UP Free x86 compatible
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Sat Dec 15 19:29:31.000 2012 (UTC + 4:00)
System Uptime: not available
Process Uptime: not available
......................
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(8d8.1084): Access violation - code c0000005 (first/second chance not available)
eax=fffffffd ebx=005d0d78 ecx=0022f070 edx=778964f4 esi=005d0d38 edi=0022f110
eip=778964f4 esp=0022edd0 ebp=0022ede0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
778964f4 c3 ret
0:000> .ecxr
eax=00000000 ebx=7ffdf000 ecx=0022fa30 edx=778964f4 esi=0022fcf4 edi=0022fdcc
eip=0124157c esp=0022fcf4 ebp=0022fdcc iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
*** WARNING: Unable to verify checksum for dump.exe
dump!wmain+0x3c:
0124157c c70001000000 mov dword ptr [eax],1 ds:0023:00000000=????????
0:000> dv
argc = 0n1
argv = 0x00280e38
p = 0x00000000
0:000> kb
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr Args to Child
0022fdcc 01241b19 00000001 00280e38 0027f9c8 dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0022fe1c 01241d0d 0022fe30 76051194 7ffdf000 dump!__tmainCRTStartup+0x199 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 533]
0022fe24 76051194 7ffdf000 0022fe70 778ab495 dump!wmainCRTStartup+0xd [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 377]
0022fe30 778ab495 7ffdf000 7676831a 00000000 kernel32!BaseThreadInitThunk+0xe
0022fe70 778ab468 0124107d 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
0022fe88 00000000 0124107d 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> u .
dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]:
0124157c c70001000000 mov dword ptr [eax],1
01241582 33c0 xor eax,eax
01241584 5f pop edi
01241585 5e pop esi
01241586 5b pop ebx
01241587 81c4cc000000 add esp,0CCh
0124158d 3bec cmp ebp,esp
0124158f e8c0fbffff call dump!ILT+335(__RTC_CheckEsp) (01241154)
0:000> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
GetPageUrlData failed, server returned HTTP status 404
URL requested: http://watson.microsoft.com/StageOne/dump_exe/0_0_0_0/50cc9743/dump_exe/0_0_0_0/50cc9743/c0000005/0001157c.htm?Retriage=1
FAULTING_IP:
dump!wmain+3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0124157c c70001000000 mov dword ptr [eax],1
EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 0124157c (dump!wmain+0x0000003c)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 00000000
Attempt to write to address 00000000
DEFAULT_BUCKET_ID: NULL_POINTER_WRITE
PROCESS_NAME: dump.exe
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
EXCEPTION_PARAMETER1: 00000001
EXCEPTION_PARAMETER2: 00000000
WRITE_ADDRESS: 00000000
FOLLOWUP_IP:
dump!wmain+3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0124157c c70001000000 mov dword ptr [eax],1
MOD_LIST: <ANALYSIS/>
FAULTING_THREAD: 00001084
PRIMARY_PROBLEM_CLASS: NULL_POINTER_WRITE
BUGCHECK_STR: APPLICATION_FAULT_NULL_POINTER_WRITE
LAST_CONTROL_TRANSFER: from 01241b19 to 0124157c
STACK_TEXT:
0022fdcc 01241b19 00000001 00280e38 0027f9c8 dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp @ 35]
0022fe1c 01241d0d 0022fe30 76051194 7ffdf000 dump!__tmainCRTStartup+0x199 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 533]
0022fe24 76051194 7ffdf000 0022fe70 778ab495 dump!wmainCRTStartup+0xd [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 377]
0022fe30 778ab495 7ffdf000 7676831a 00000000 kernel32!BaseThreadInitThunk+0xe
0022fe70 778ab468 0124107d 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
0022fe88 00000000 0124107d 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND: ~0s; .ecxr ; kb
FAULTING_SOURCE_CODE:
31: int _tmain(int argc, _TCHAR* argv[])
32: {
33: SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
34: int* p = NULL;
> 35: *p = 1;
36: return 0;
37: }
38:
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: dump!wmain+3c
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: dump
IMAGE_NAME: dump.exe
DEBUG_FLR_IMAGE_TIMESTAMP: 50cc9743
FAILURE_BUCKET_ID: NULL_POINTER_WRITE_c0000005_dump.exe!wmain
BUCKET_ID: APPLICATION_FAULT_NULL_POINTER_WRITE_dump!wmain+3c
WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/dump_exe/0_0_0_0/50cc9743/dump_exe/0_0_0_0/50cc9743/c0000005/0001157c.htm?Retriage=1
Followup: MachineOwner
---------
Upvotes: 9
Reputation: 69724
To keep the exception context intact you can create the minidump from an outer process, which debugs the process of interest with DebugActiveProcess
API and receives exception events as a part of debugging. Minidump creation preceding release of the debugee with ContinueDebugEvent
preserves call stack and exception context.
Upvotes: 1
Reputation: 421
Try using AddVectoredExceptionHandler. The thread context of the moment of exception is passed as an argument to the callback proc of this method.
Upvotes: 1