How To Debug

These are my debugging notes.

The magic symbol path is SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols

Given a crashed process:

0:001> kb
ChildEBP RetAddr  Args to Child              
44fedb5c 77f7f49f 77e74bd8 00000002 44fedba8 SharedUserData+0x304
44fedb60 77e74bd8 00000002 44fedba8 00000001 ntdll!ZwWaitForMultipleObjects+0xc
44fedbfc 77e74c70 00000002 44fedcd0 00000000 kernel32!WaitForMultipleObjectsEx+0x12c
44fedc14 69455a73 00000002 44fedcd0 00000000 kernel32!WaitForMultipleObjects+0x17
44fee398 69456ba3 44fef96c ffffffff 00008310 faultrep!StartDWException+0x575
44fef400 77eb9d66 44fef96c ffffffff c0000005 faultrep!ReportFault+0x488
44fef924 77c313c8 44fef96c 77c140c8 00000000 kernel32!UnhandledExceptionFilter+0x2e2
44fef940 77c37fde 00000000 44fef96c 77c33efb MSVCRT!_XcptFilter+0x15f
44feffb4 77e802ed 00862e60 0006f96c 77f519f3 MSVCRT!_endthreadex+0xc6
44feffec 00000000 77c37f49 00862e60 00000000 kernel32!BaseThreadStart+0x37
The first param to kernel32!UnhandledExceptionFilter (44fef96c) is a pointer to an EXCEPTION_POINTERS struct.
0:001> dd 44fef96c
44fef96c  44fefa5c 44fefa78 44fef998 77f833a0
44fef97c  44fefa5c 44feffa4 44fefa78 44fefa34
44fef98c  44feffa4 77f833b4 44feffa4 44fefa44
The second pointer in the struct is the pointer to the CONTEXT_RECORD. Use .cxr addr to reset the debuggers context to the thread as it was when it faulted. (Use ~s to return to the thread's current context.)
0:001> .cxr 44fefa78
eax=00000000 ebx=00000001 ecx=00000841 edx=44b9c1d8 esi=493dfad8 edi=44fefde4
eip=6d476a25 esp=44fefd44 ebp=44fefd74 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
jvm!JVM_FindSignal+1ef27:
6d476a25 837cc21400 cmp dword ptr [edx+eax*8+0x14],0x0 ds:0023:44b9c1ec=????????
The first pointer in the struct is the pointer to the EXCEPTION_RECORD. Use .exr addr to dump the struct.
0:001> .exr 44fefa5c
ExceptionAddress: 6d476a25 (jvm!JVM_FindSignal+0x0001ef27)
   ExceptionCode: c0000005
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 44b9c1ec
Attempt to read from address 44b9c1ec

More useful command examples:

x kernel32!*Ctrl* search for symbol
~*kb dump stack of all threads
bp 77e9658d "r eax=0;g" create breakpoint that executes command when hit
bl list breakpoints
u kernel32!CreateEventA disassemble
Stack Frame Layout

Push moves the stack pointer backward in memory (ie, esp -= 4) and then writes the given value to location pointed at by the stack pointer.

Stack frame layout (no frame pointer optimization)

this function's ebp
points here ------------\
    ebp-0x8   ebp-0x4   ebp+0x0   ebp+0x4   ebp+0x8   ebp+0xC
                        caller's  return 
    local1    local0    ebp       addr      param0    param1
... 00000000  00000000  00000000  00000000  00000000  00000000 ...
Calling Conventions

All arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the eax register, except for 8-byte structures, which are returned in the edx:eax register pair. Larger structures are returned in the eax register as pointers to hidden return structures. Parameters are pushed onto the stack from right to left.

The compiler generates prolog and epilog code to save and restore the esi, edi, ebx, and ebp registers, if they are used in the function.

name argument passing stack cleanup name decoration int func(int a, double b)
cdecl on stack, reverse order / right to left (ebp+0x8 is param0, ebp+0xC is param1 ...) caller prefix: "_" _func
stdcall on stack, reverse order / right to left (ebp+0x8 is param0, ebp+0xC is param1 ...) callee prefix: "_"; suffix: "@" followed by the number of bytes (in decimal) in the argument list. _func@12
fastcall The first two DWORD or smaller arguments are passed in ecx and edx registers; all other arguments are passed on stack, reverse order / right to left (ebp+0x8 is param2, ebp+0xC is param3 ...) callee prefix: "@"; suffix: "@" followed by the number of bytes (in decimal) in the argument list. @func@12
thiscall this in ecx; all other arbuments are passed on stack, reverse order / right to left (ebp+0x8 is param0, ebp+0xC is param1 ...); callee (C++ mangling)
Inline Assembler

__asm { int 3 }
hardcoded debug breakpoint
#define TEB_OFFSET 4
void ** ppvStackBase;
__asm { mov eax, fs:[TEB_OFFSET] }
__asm { mov ppvStackBase, eax }
stack base from TEB
void ** ppvFrame;
_asm { mov ppvFrame, ebp }
frame pointer
C o m m e n t s :     updated: 2007-05-04 (3643 days ago)
Can you please explain us what is Frame Pointer Optimization (FPO)...... Also could you explain in detail about the Stacks and the ESP and EBP in the stacks with some simple examples. Would appreicate your help! Thanks Sriram Rajendran
2007-05-03 : Did the arguments to kernel32!UnhandledExceptionFilter change with Windows Server 2003 SP1? I'm seeing what appears to be the EXCEPTION_POINTERS structure in the *third* argument (the first arg is *not* on the stack, but is in the UnhandledExceptionFilter code.

For example:
ChildEBP RetAddr Args to Child
056ae6d4 7c821b74 773d59cf 50000018 00000004 ntdll!KiFastSystemCallRet
056ae6d8 773d59cf 50000018 00000004 00000003 ntdll!NtRaiseHardError+0xc
056ae734 773bde9b 039ad9e0 042ece30 00012010 user32!ServiceMessageBox+0x145
056ae890 773b1a28 056ae89c 00000028 00000000 user32!MessageBoxWorker+0x13e
056ae8e8 773d5e47 00000000 039ad9e0 042ece30 user32!MessageBoxTimeoutW+0x7a
056ae91c 773bdd8b 00000000 056ae9c0 7c37f480 user32!MessageBoxTimeoutA+0x9c
056ae93c 773bd923 00000000 056ae9c0 7c37f480 user32!MessageBoxExA+0x1b
056ae958 7c34c224 00000000 056ae9c0 7c37f480 user32!MessageBoxA+0x45
056ae98c 7c348e6c 056ae9c0 7c37f480 00212010 msvcr71!__crtMessageBoxA+0xf4
056aeba8 7c34cf83 0000000a 056aef34 056af2a8 msvcr71!_NMSG_WRITE+0x12e
056aebe0 77e99e3a 056af2a8 201c5688 03724df0 msvcr71!abort+0x7
056aebd8 7c35f0a8 7c35f07d 77e99e3a 056af2a8 kernel32!UnhandledExceptionFilter+0x14d
056aebe4 056af2a8 201c5688 03724df0 056affa8 msvcr71!__CxxUnhandledExceptionFilter+0x2b
WARNING: Frame IP not in any known module. Following frames may be wrong.
056af264 201bc619 056af2a8 00000000 056affa8 0x56af2a8
056af27c 201b75a6 e06d7363 056af2a8 201b792f usercode!DllUnregisterServer+0xb177
056affb8 77e6608b 03724df0 00000000 00000000 usercode!DllUnregisterServer+0x6104
056affec 00000000 201b7518 03724df0 00000000 kernel32!BaseThreadStart+0x34

-- Ray Bloom


2007-05-04 : I agree, the third parameter (056af2a8) looks like the address of the EXCEPTION_POINTERS struct (it's on the stack, and it's passed along to other functions). I don't know whether kernel32!UnhandledExceptionFilter has changed in Win 2003 Srv. It could have, but it seems like that might cause compatibility problems. My guess is that you are seeing some FPO funkiness. 7c35f0a8, 7c35f07d, and 77e99e3a all look like return addresses to me.
-- Louis! :)
Edit