My application, an executable, is crashing on a remote machine. I don't have access to that machine, so I requested a dump, generated through Task Manager. Using WinDbg, on executing the command !analyze -v
, I can see the following text among many others
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 0000000000000000
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 0
How can I know if it is responsible for the crash? If it is not, how do I identify the real cause?
TLDR: if !findstack kernel32!WerpReportFault
yields a result, then it's probably not the root cause.
Long version:
When your application crashes due to an unhandled exception, the OS will pick it up with a feature called Windows Error Reporting. This results in a few technical things:
ntdll
starts a new thread.kernel32
) which shows the dialogIf you take a crash dump at that time, you'll see the following:
A breakpoint exception as mentioned in your question
0:002> .exr -1
ExceptionAddress: 775f000c (ntdll!DbgBreakPoint)
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 1
Parameter[0]: 00000000
A thread that has nothing inside but a breakpoint
0:002> k
ChildEBP RetAddr
02e2ff58 7767f926 ntdll!DbgBreakPoint
02e2ff88 75b3338a ntdll!DbgUiRemoteBreakin+0x3c
02e2ff94 77619f72 kernel32!BaseThreadInitThunk+0xe
02e2ffd4 77619f45 ntdll!__RtlUserThreadStart+0x70
02e2ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
A call stack with the related actions mentioned before
0:001> k
ChildEBP RetAddr
01aff904 770715f7 ntdll!NtWaitForMultipleObjects+0x15
01aff9a0 75b319f8 KERNELBASE!WaitForMultipleObjectsEx+0x100
01aff9e8 75b34200 kernel32!WaitForMultipleObjectsExImplementation+0xe0
01affa04 75b580a4 kernel32!WaitForMultipleObjects+0x18
01affa70 75b57f63 kernel32!WerpReportFaultInternal+0x186
01affa84 75b57858 kernel32!WerpReportFault+0x70
01affa94 75b577d7 kernel32!BasepReportFault+0x20
01affb20 776574ff kernel32!UnhandledExceptionFilter+0x1af
01affb28 776573dc ntdll!__RtlUserThreadStart+0x62
01affb3c 77657281 ntdll!_EH4_CallFilterFunc+0x12
01affb64 7763b499 ntdll!_except_handler4+0x8e
01affb88 7763b46b ntdll!ExecuteHandler2+0x26
01affbac 7763b40e ntdll!ExecuteHandler+0x24
01affc38 775f0133 ntdll!RtlDispatchException+0x127
01affc38 6f8c20ce ntdll!KiUserExceptionDispatcher+0xf
To identify a WER breakpoint, you can check for these three conditions. For the latter, you can use the !findstack
command, since it may happen on any thread.
0:001> !findstack kernel32!WerpReportFault
Thread 001, 2 frame(s) match
* 04 01affa70 75b57f63 kernel32!WerpReportFaultInternal+0x186
* 05 01affa84 75b57858 kernel32!WerpReportFault+0x70
I hope that the method name does not change.
This works for x86 (32 bit) due to the way how the stack is created. It does not work well on x64 (64 bit), since the kb
command is not reliable. On x64, arguments get passed in registers instead of the stack but the kb
command only works with the stack.
That said, the exception pointer is passed to WerpReportFault()
as the second argument. You can use that exception pointer to create a new dump with that exception as the primary exception like this:
.dump /ma /xp <exception pointer> c:\path\to\newdump.dmp
Next, close the source dump, open the new dump and analyze it again, e.g. with the following 4 commands as a starting point:
.symfix
.reload
.exr -1
!analyze -v
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With