Debugging Tools for Windows

Anatomy of a Stack Trace

Basic stack information is stored in the registers. Use the r (Registers) command to display these:

kd> r  [This command displays register values.]
eax=c0000018 ebx=80621828 ecx=00000000 edx=807da761 esi=e12e0e28 edi=e12df868
eip=f28343b3 esp=f2c132cc ebp=f2c132f0 iopl=0         nv up ei pl zr na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
VIDEOPRT!pVideoPortReportResourceList+0x263:
f28343b3 8db340010000     lea     esi,[ebx+0x140]   ds:0023:80621968=00000000 

The registers are used as follows:

A stack trace could be diagrammed in the following manner:

The stack trace displayed on a kernel debugger is written in assembly code. A simple set of instructions in assembly code could look like this:

push ebp      ;Places the caller's base pointer (ebp) onto the stack
mov ebp,esp         ;Sets the base pointer (ebp) equal to the stack pointer (esp)
mov eax, [ebp+8]    ;Grab the value of the first argument off the stack and store it in eax
add eax, [ebp+c]    ;Add the second argument's value to the value in eax
pop ebp             ;Restore the caller's base pointer
ret 8               ;Return to the calling function and remove 8 bytes from the stack 

The compiler can optimize this code, simplifying it so it is shorter and more direct. An optimized routine might look like the following (note how the code omits references to the base pointer):

mov eax, [esp+4]
add eax, [esp+8]
ret 8 

Finally following is how it would look in C:

ULONG Add(ULONG a, ULONG b)
{
    return a + b;

Build machine: CAPEBUILD