WinDBG - Finding the actual (unmanaged) exception

13,315

Solution 1

Switching the context should've brought you to the RaiseException() invocation. If you look it up, it accepts an exception code and a bunch of application/compiler-specific parameters in the parameters block. Visual studio compiler will passes exception object as one of the parameters, i.e.:

0:003:x86> .cxr <addr-of-context-record>
0:003:x86> dds 2bffb28 la
02bffb28  02bffb60
02bffb2c  7222872d MSVCR100!CxxThrowException+0x45  ; this is the RaiseException() call
02bffb30  e06d7363 ; c++ exception code
02bffb34  00000001 ; flags
02bffb38  00000003 ; number of parameters
02bffb3c  02bffb54 ; parameters
...

0:003:x86> dpp 02bffb54 l3
02bffb54  19930520 ; compiler magic
02bffb58  02bffb70 0016c8b0 mymodule!std::bad_alloc::`vftable'
02bffb5c  0016f088 ; exception descriptor area (compiler-specific)
...

Then, you can use dt 02bffb70 mymodule!std::bad_alloc to inspect the exception object

Solution 2

You may try this to look for a context signature in the process memory:

s -d 0 L10000000/4 0001003f

with some luck this will return a memory address where the context was found, you can then set the current context to this location with .cxr.

This works because the CONTEXT structure in windows, created when an exception is raised, always begins with the 0001003f value (only valid for X86!)

(tip taken from the Advanced Windows Debugging book)

Share:
13,315
Yochai Timmer
Author by

Yochai Timmer

"Yes, but your program doesn't work. If mine doesn't have to work, I can make it run instantly and take up no memory. "

Updated on June 04, 2022

Comments

  • Yochai Timmer
    Yochai Timmer almost 2 years

    I'm trying to find the actual exception in a managed-unmanaged mixed code.

    The problem is that I have a .Net class that catches all unhandled exceptions and then creates a dump, so when i look at the dump there's mixed managed-unmanaged code, and i can't really get to the actual unmanaged exception.
    And to make things worse, the .Net seems to have its own exception so !analyze -v gives me that exception.

    So, here is what I have:

    I can find where the exception happened (by finding the 1003f word), then do .cxr to get to that actual place in the code.

    When I do a !dumpstack I get something like:

    //My module stuff and then:
    122bf71c 08bf5242 (MethodDesc 0x4bf71ac +0x5a <Module>.dbg.NativeExceptionHandler())
    122bf734 08bf5242 (MethodDesc 0x4bf71ac +0x5a <Module>.dbg.NativeExceptionHandler())
    122bf73c 08bf51ce (MethodDesc 0x4bf71dc +0x6 <Module>.dbg.OnUnhandledNativeException(_EXCEPTION_POINTERS*)), calling (MethodDesc 0x4bf71ac +0 <Module>.dbg.NativeExceptionHandler())
    122bf75c 08bf51ce (MethodDesc 0x4bf71dc +0x6 <Module>.dbg.OnUnhandledNativeException(_EXCEPTION_POINTERS*)), calling (MethodDesc 0x4bf71ac +0 <Module>.dbg.NativeExceptionHandler())
    122bf760 3944bf15 3944bf15
    122bf778 7c35f0c3 msvcr71!__CxxUnhandledExceptionFilter+0x46, calling 091f15a2
    122bf784 7c864191 kernel32!UnhandledExceptionFilter+0x1c7
    122bf7ac 7c812afb kernel32!RaiseException+0x53, calling ntdll!RtlRaiseException
    122bf7f4 7857df60 msvcr90!_CxxThrowException+0x48 [f:\prebuild\eh\throw.cpp:161], calling kernel32!RaiseException
    122bf828 785436c5 msvcr90!__set_flsgetvalue+0xf [f:\src\tidtable.c:256], calling kernel32!TlsGetValue
    122bf834 785438b3 msvcr90!_getptd_noexit+0x74 [f:\src\tidtable.c:616], calling ntdll!RtlSetLastWin32Error
    122bf844 785438c5 msvcr90!_getptd+0x8 [f:\src\tidtable.c:641], calling msvcr90!_getptd_noexit [f:\src\tidtable.c:566]
    122bf84c 7857c98c msvcr90!__FrameUnwindToState+0xd9 [f:\prebuild\eh\frame.cpp:1161], calling msvcr90!_getptd [f:\src\tidtable.c:640]
    122bf850 7857c972 msvcr90!__FrameUnwindToState+0xbf [f:\prebuild\eh\frame.cpp:1182], calling msvcr90!__SEH_epilog4
    122bf860 785436c5 msvcr90!__set_flsgetvalue+0xf [f:\src\tidtable.c:256], calling kernel32!TlsGetValue
    122bf870 785436c5 msvcr90!__set_flsgetvalue+0xf [f:\src\tidtable.c:256], calling kernel32!TlsGetValue
    122bf87c 785438b3 msvcr90!_getptd_noexit+0x74 [f:\src\tidtable.c:616], calling ntdll!RtlSetLastWin32Error
    122bf88c 785438c5 msvcr90!_getptd+0x8 [f:\src\tidtable.c:641], calling msvcr90!_getptd_noexit [f:\src\tidtable.c:566]
    122bf894 7857d06a msvcr90!CallCatchBlock+0x148 [f:\prebuild\eh\frame.cpp:1503], calling msvcr90!_getptd [f:\src\tidtable.c:640]
    122bf898 7857d03c msvcr90!CallCatchBlock+0x11a [f:\prebuild\eh\frame.cpp:1520], calling msvcr90!__SEH_epilog4
    122bf8e8 7857d03c msvcr90!CallCatchBlock+0x11a [f:\prebuild\eh\frame.cpp:1520], calling msvcr90!__SEH_epilog4
    122bf8ec 7857d486 msvcr90!CatchIt+0x5e [f:\prebuild\eh\frame.cpp:1275], calling msvcr90!CallCatchBlock [f:\prebuild\eh\frame.cpp:1433]
    122bf91c 7857d576 msvcr90!FindHandlerForForeignException+0xdb [f:\prebuild\eh\frame.cpp:976], calling msvcr90!CatchIt [f:\prebuild\eh\frame.cpp:1219]
    122bf950 785436c5 msvcr90!__set_flsgetvalue+0xf [f:\src\tidtable.c:256], calling kernel32!TlsGetValue
    122bf95c 785438b3 msvcr90!_getptd_noexit+0x74 [f:\src\tidtable.c:616], calling ntdll!RtlSetLastWin32Error
    122bf96c 785438c5 msvcr90!_getptd+0x8 [f:\src\tidtable.c:641], calling msvcr90!_getptd_noexit [f:\src\tidtable.c:566]
    122bf974 7857d8c8 msvcr90!FindHandler+0x334 [f:\prebuild\eh\frame.cpp:879], calling msvcr90!_getptd [f:\src\tidtable.c:640]
    122bf988 785436c5 msvcr90!__set_flsgetvalue+0xf [f:\src\tidtable.c:256], calling kernel32!TlsGetValue
    122bf994 785438b3 msvcr90!_getptd_noexit+0x74 [f:\src\tidtable.c:616], calling ntdll!RtlSetLastWin32Error
    122bf998 7c910323 ntdll!RtlpImageNtHeader+0x56, calling ntdll!_SEH_epilog
    122bf9b0 7c90d98a ntdll!NtQueryVirtualMemory+0xc
    122bf9b4 7c880b54 kernel32!_ValidateEH3RN+0xb6, calling ntdll!ZwQueryVirtualMemory
    122bf9f4 7c83ab50 kernel32!BaseThreadStart+0x4d, calling kernel32!UnhandledExceptionFilter
    122bf9fc 7c839b39 kernel32!_except_handler3+0x61
    122bfa24 7c9032a8 ntdll!ExecuteHandler2+0x26
    122bfa48 7c90327a ntdll!ExecuteHandler+0x24, calling ntdll!ExecuteHandler2
    122bfa6c 7c92aa0f ntdll!RtlDispatchException+0xb1, calling ntdll!RtlpExecuteHandlerForException
    122bfa98 78591795 msvcr90!_except_handler3+0x69
    122bfac0 7c9032a8 ntdll!ExecuteHandler2+0x26
    122bfae4 7c90327a ntdll!ExecuteHandler+0x24, calling ntdll!ExecuteHandler2
    122bfaf8 7c90e48a ntdll!KiUserExceptionDispatcher+0xe, calling ntdll!RtlDispatchException
    122bfdf8 064fdd84 MyModule!Class::MyFunction::Update+0xe4 [c:\MyCode.cpp:12345] ====> Exception cxr@122bfb2c
    122bfb60 7c910222 ntdll!RtlpAllocateFromHeapLookaside+0x42, calling ntdll!_SEH_epilog
    

    Anyway, so the thing is, I can't get the actual exception. I know it's an std exception, but I'm not sure which one (in that line of code there isn't a custom exception, and a number of things could have gone wrong).

  • Yochai Timmer
    Yochai Timmer over 12 years
    I found the context already, and found the exact line where the exception happened. The thing is that after i cahnge to the context with .cxr I don't know how to ge tthe exception information.
  • Yochai Timmer
    Yochai Timmer over 12 years
    Thanks, I get roughly what you get, but instead of the line with the mymodule!std::bad_alloc::`vftable' I get 00000000 ... so there's nothing i can get from there.
  • Yochai Timmer
    Yochai Timmer over 12 years
    Any idea why it would be 000000 there ? (before the exception descriptor)
  • floyd73
    floyd73 over 12 years
    sorry, I didn't read the question carefully and thought that you were looking for the context in the first place
  • user2371301
    user2371301 over 12 years
    can you dump arguments to RaiseException in your case?
  • user2371301
    user2371301 over 12 years
    it would also be helpful to take a look at the unmanaged stack (kb), after you've fixed the symbols
  • Yochai Timmer
    Yochai Timmer over 12 years
    I've pasted it as another question, because you actually helped me with what i was looking for. stackoverflow.com/questions/7309072/…
  • user2371301
    user2371301 over 12 years
    yes, but the dumpstack seems inconclusive regarding the unmanaged stack, you have an actual failure down the stack, in the Update method, I wanted to take a look at it.
  • user2371301
    user2371301 over 12 years