Windbg Crash Dump Stack Trace Keeps Every Over Function

249 views Asked by At

So I have a crash dump, and using WinDbg, I am able to get the stack trace. However, it appears to be skipping every other function. For instance if the actual code is:

void a()
{
  b();
}
void b()
{
  c();
}
void c(){}

The stack trace would have a, and c in the stack frame and not b. Is this expected behavior, and is there something I can do to see the entire stack trace? I have using the command "kn" to view the stack trace.

2

There are 2 answers

1
Player On

Like already mentioned by Lieven. this is a case where compiler is making function calls inline.

There are 2 things that i would suggest:

a. If you have control over the code and build environment. Build a non-optimized/debug version of the code. This will ensure that compiler does not inline functions on its own.

b. In WinDBG you can see the disassembly under View --> Disassembly. Here you can see that code for function b() is actually in lined under a(). In case you are comfortable with assembly debugging you can get the value of locals as well :)

0
Thomas Weller On

The compiler may optimize the code. One optimization is to inline methods so that call and ret statements and everything related (push, pop etc.) are removed.

For demonstration purposes, I have added a std::cout statement to your code which we can identify so that the full code now reads

#include "stdafx.h"
#include <iostream>

void c()
{
    std::cout <<  "Hello world";
}

void b()
{
    c();
}

void a()
{
    b();
}

int _tmain(int argc, _TCHAR* argv[])
{
    a();
    return 0;
}

Walkthrough in debug build

In a typical debug build, there are no optimizations and you can see the methods. To follow the example, start WinDbg first and run the executable via File/Open executable....

0:000> .symfix e:\debug\symbols

0:000> lm
start    end        module name
010d0000 010f3000   OptimizedInlined   (deferred)             
...

0:000> ld OptimizedInlined
Symbols loaded for OptimizedInlined

0:000> x OptimizedInlined!c
010e50c0          OptimizedInlined!c (void)

0:000> bp OptimizedInlined!c

0:000> bl
 0 e 010e50c0     0001 (0001)  0:**** OptimizedInlined!c

 0:000> g
Breakpoint 0 hit
eax=cccccccc ebx=7efde000 ecx=00000000 edx=00000001 esi=00000000 edi=003ffa00
eip=010e50c0 esp=003ff930 ebp=003ffa00 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
OptimizedInlined!c:
010e50c0 55              push    ebp

0:000> u eip L18
OptimizedInlined!c [e:\...\optimizedinlined.cpp @ 8]:
010e50c0 55              push    ebp
010e50c1 8bec            mov     ebp,esp
010e50c3 81ecc0000000    sub     esp,0C0h
010e50c9 53              push    ebx
010e50ca 56              push    esi
010e50cb 57              push    edi
010e50cc 8dbd40ffffff    lea     edi,[ebp-0C0h]
010e50d2 b930000000      mov     ecx,30h
010e50d7 b8cccccccc      mov     eax,0CCCCCCCCh
010e50dc f3ab            rep stos dword ptr es:[edi]
010e50de 6854ca0e01      push    offset OptimizedInlined!`string' (010eca54)
010e50e3 a1e4000f01      mov     eax,dword ptr [OptimizedInlined!_imp_?coutstd (010f00e4)]
010e50e8 50              push    eax
010e50e9 e8c9c1ffff      call    OptimizedInlined!ILT+690(??$?6U?$char_traitsDstdstdYAAAV?$basic_ostreamDU?$char_traitsDstd (010e12b7)
010e50ee 83c408          add     esp,8
010e50f1 5f              pop     edi
010e50f2 5e              pop     esi
010e50f3 5b              pop     ebx
010e50f4 81c4c0000000    add     esp,0C0h
010e50fa 3bec            cmp     ebp,esp
010e50fc e838c2ffff      call    OptimizedInlined!ILT+820(__RTC_CheckEsp) (010e1339)
010e5101 8be5            mov     esp,ebp
010e5103 5d              pop     ebp
010e5104 c3              ret

Walkthrough release build

In the release build, see how things change. The WinDbg commands are the same, but the methods c(), b() and a() cannot be found. The std::cout method call has been inlined into wmain():

0:000> .symfix e:\debug\symbols

0:000> lm
start    end        module name
01360000 01367000   OptimizedInlined   (deferred)             
...

0:000> ld OptimizedInlined
Symbols loaded for OptimizedInlined

0:000> x OptimizedInlined!c

0:000> x OptimizedInlined!b

0:000> x OptimizedInlined!a

0:000> x OptimizedInlined!wmain
013612a0          OptimizedInlined!wmain (int, wchar_t **)

0:000> bp OptimizedInlined!wmain

0:000> bl
 0 e 013612a0     0001 (0001)  0:**** OptimizedInlined!wmain

 0:000> g
Breakpoint 0 hit
eax=6142f628 ebx=00000000 ecx=0087a6e8 edx=0019def8 esi=00000001 edi=00000000
eip=013612a0 esp=0042f8f8 ebp=0042f934 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
OptimizedInlined!wmain:
013612a0 8b0d44303601    mov     ecx,dword ptr [OptimizedInlined!_imp_?coutstd (01363044)] ds:002b:01363044={MSVCP120!std::cout (646c6198)}

0:000> u eip L4
OptimizedInlined!wmain [e:\...\optimizedinlined.cpp @ 23]:
013612a0 8b0d44303601    mov     ecx,dword ptr [OptimizedInlined!_imp_?coutstd (01363044)]
013612a6 e895040000      call    OptimizedInlined!std::operator<<<std::char_traits<char> > (01361740)
013612ab 33c0            xor     eax,eax
013612ad c3              ret