[lldb-dev] Unwinding with no symbols

Zachary Turner zturner at google.com
Fri Apr 3 15:43:09 PDT 2015


Hi Jason,

I know we talked about this a long time ago with regards to stepping over a
method that you don't have symbols for.  At that time, the conclusion was
that we should get at least function bounds for each function, otherwise we
can't guarantee that we'll be able to unwind properly.  I plan to do that
(fairly soon), but in the meantime I want to see if we can improve the
unwinder in the presence of no symbols.  I think this is still a useful
thing to have, and could potentially be an easy fix.  Currently if I try to
do this, I get the following output from LLDB.

(lldb) Process 10848 stopped
* thread #1: tid = 0x11fc, 0x011882be simple_step.exe`main(argc=1,
argv=0x015e3be0) + 606 at simple_step.cpp:19, stop reason = breakpoint 1.3
    frame #0: 0x011882be simple_step.exe`main(argc=1, argv=0x015e3be0) +
606 at simple_step.cpp:19
   16       std::cout << "fib(5) = " << fib(5) << std::endl;
   17       std::cout << "fib(6) = " << fib(6) << std::endl;
   18
-> 19       printf("The value of fib(7) is %u\n", fib(7));
   20       return 0;
   21   }
(lldb) bt
* thread #1: tid = 0x11fc, 0x011882be simple_step.exe`main(argc=1,
argv=0x015e3be0) + 606 at simple_step.cpp:19, stop reason = breakpoint 1.3
  * frame #0: 0x011882be simple_step.exe`main(argc=1, argv=0x015e3be0) +
606 at simple_step.cpp:19
    frame #1: 0x01190a41 simple_step.exe
    frame #2: 0x75107c04 kernel32.dll`BaseThreadInitThunk + 36
    frame #3: 0x7774b54f ntdll.dll`RtlInitializeExceptionChain + 143
    frame #4: 0xffffffff
(lldb) thread step-over
(lldb) Process 10848 stopped
* thread #1: tid = 0x11fc, 0x01190a41 simple_step.exe, stop reason = step
over
    frame #0: 0x01190a41 simple_step.exe
->  0x1190a41: addl   $0xc, %esp
    0x1190a44: movl   %eax, %esi
    0x1190a46: movl   %esi, -0x24(%ebp)
    0x1190a49: testl  %ebx, %ebx
(lldb) bt
* thread #1: tid = 0x11fc, 0x01190a41 simple_step.exe, stop reason = step
over
  * frame #0: 0x01190a41 simple_step.exe
    frame #1: 0x75107c04 kernel32.dll`BaseThreadInitThunk + 36
    frame #2: 0x7774b54f ntdll.dll`RtlInitializeExceptionChain + 143
    frame #3: 0xffffffff



0x1190a41 if you look at the original callstack is higher up on the frame
than main(), so it's basically the function in the CRT that calls main.


th1/fr0 with pc value of 0x11882be, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882be cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11882be, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882be cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 supplying caller's saved eip (8)'s location using assembly insn
profiling UnwindPlan
th1/fr0 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fbb8]
 th1/fr1 pc = 0x1190a41
th1/fr0 supplying caller's saved ebp (6)'s location using assembly insn
profiling UnwindPlan
th1/fr0 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -8 [saved at 0x114fbb4]
 th1/fr1 fp = 0x114fbfc
th1/fr0 supplying caller's saved esp (7)'s location using assembly insn
profiling UnwindPlan
th1/fr0 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fbbc]
 th1/fr1 sp = 0x114fbbc
 th1/fr1 with pc value of 0x1190a41, no symbol/function name is known.
 th1/fr1 Backing up the pc value of 0x1190a41 by 1 and re-doing symbol
lookup; old symbol was
 th1/fr1 Symbol is now
 th1/fr1 active row: 0x0000000001190a41: CFA=ebp +8 => esp=CFA+0
ebp=[CFA-8] eip=[CFA-4]

th1/fr0 supplying caller's saved ebp (6)'s location, cached
 th1/fr1 CFA is 0x114fc04: Register ebp (6) contents are 0x114fbfc, offset
is 8
 th1/fr1 m_cfa = 0x114fc04
 th1/fr1 initialized frame current pc is 0x1190a41 cfa is 0x114fc04
th1/fr0 supplying caller's saved eip (8)'s location, cached
 th1/fr1 supplying caller's saved eip (8)'s location using i386 default
unwind plan UnwindPlan
 th1/fr1 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fc00]
  th1/fr2 pc = 0x75107c04
 th1/fr1 supplying caller's saved ebp (6)'s location using i386 default
unwind plan UnwindPlan
 th1/fr1 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -8 [saved at 0x114fbfc]
  th1/fr2 fp = 0x114fc10
 th1/fr1 supplying caller's saved esp (7)'s location using i386 default
unwind plan UnwindPlan
 th1/fr1 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc04]
  th1/fr2 sp = 0x114fc04
  th1/fr2 with pc value of 0x75107c04, symbol name is 'BaseThreadInitThunk'
  th1/fr2 active row: 0x0000000075107bf1: CFA=ebp +8 => esi=[CFA-16]
ebp=[CFA-8] esp=CFA+0 eip=[CFA-4]

 th1/fr1 supplying caller's saved ebp (6)'s location, cached
  th1/fr2 CFA is 0x114fc18: Register ebp (6) contents are 0x114fc10, offset
is 8
  th1/fr2 m_cfa = 0x114fc18
  th1/fr2 initialized frame current pc is 0x75107c04 cfa is 0x114fc18
 th1/fr1 supplying caller's saved eip (8)'s location, cached
  th1/fr2 supplying caller's saved eip (8)'s location using assembly insn
profiling UnwindPlan
  th1/fr2 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fc14]
   th1/fr3 pc = 0x7774b54f
  th1/fr2 supplying caller's saved ebp (6)'s location using assembly insn
profiling UnwindPlan
  th1/fr2 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -8 [saved at 0x114fc10]
   th1/fr3 fp = 0x114fc58
  th1/fr2 supplying caller's saved esp (7)'s location using assembly insn
profiling UnwindPlan
  th1/fr2 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc18]
   th1/fr3 sp = 0x114fc18
   th1/fr3 with pc value of 0x7774b54f, symbol name is
'RtlInitializeExceptionChain'
   th1/fr3 active row: 0x000000007774b504: CFA=ebp+12 => ebp=[CFA-12]
esp=CFA+0 eip=[CFA-4]

  th1/fr2 supplying caller's saved ebp (6)'s location, cached
   th1/fr3 CFA is 0x114fc64: Register ebp (6) contents are 0x114fc58,
offset is 12
   th1/fr3 m_cfa = 0x114fc64
   th1/fr3 initialized frame current pc is 0x7774b54f cfa is 0x114fc64
  th1/fr2 supplying caller's saved eip (8)'s location, cached
   th1/fr3 supplying caller's saved eip (8)'s location using assembly insn
profiling UnwindPlan
   th1/fr3 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fc60]
    th1/fr4 pc = 0xffffffff
   th1/fr3 supplying caller's saved ebp (6)'s location using assembly insn
profiling UnwindPlan
   th1/fr3 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -12 [saved at 0x114fc58]
    th1/fr4 fp = 0x114fc68
   th1/fr3 supplying caller's saved esp (7)'s location using assembly insn
profiling UnwindPlan
   th1/fr3 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc64]
    th1/fr4 sp = 0x114fc64
    th1/fr4 using architectural default unwind method
   th1/fr3 supplying caller's saved ebp (6)'s location, cached
    th1/fr4 CFA is 0x114fc70: Register ebp (6) contents are 0x114fc68,
offset is 8
    th1/fr4 initialized frame cfa is 0x114fc70
   th1/fr3 supplying caller's saved eip (8)'s location, cached
    th1/fr4 supplying caller's saved eip (8)'s location using i386 default
unwind plan UnwindPlan
    th1/fr4 supplying caller's register eip (8) from the stack, saved at
CFA plus offset -4 [saved at 0x114fc6c]
     th1/fr5 pc = 0x0
    th1/fr4 supplying caller's saved ebp (6)'s location using i386 default
unwind plan UnwindPlan
    th1/fr4 supplying caller's register ebp (6) from the stack, saved at
CFA plus offset -8 [saved at 0x114fc68]
     th1/fr5 fp = 0x0
    th1/fr4 supplying caller's saved esp (7)'s location using i386 default
unwind plan UnwindPlan
    th1/fr4 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc70]
     th1/fr5 sp = 0x114fc70
     th1/fr5 this frame has a pc of 0x0
     Frame 5 invalid RegisterContext for this frame, stopping stack walk
th1 Unwind of this thread is complete.
th1/fr0 with pc value of 0x11882c5, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882c5 cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11882cb, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882cb cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11882cb, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882cb cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x1188000, function name is 'unsigned int
fib(unsigned int)'
th1/fr0 0x0000000001188000: CFA=esp +4 => esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fb40: Register esp (7) contents are 0x114fb3c, offset
is 4
th1/fr0 initialized frame current pc is 0x1188000 cfa is 0x114fb40 using
assembly insn profiling UnwindPlan
th1/fr0 supplying caller's saved eip (8)'s location using assembly insn
profiling UnwindPlan
th1/fr0 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fb3c]
 th1/fr1 pc = 0x11882d0
th1/fr0 supplying caller's register ebp (6) from the live RegisterContext
at frame 0
 th1/fr1 fp = 0x114fbb4
th1/fr0 supplying caller's saved esp (7)'s location using assembly insn
profiling UnwindPlan
th1/fr0 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fb40]
 th1/fr1 sp = 0x114fb40
 th1/fr1 with pc value of 0x11882d0, function name is 'main'
 th1/fr1 active row: 0x0000000001188060: CFA=ebp +8 => esp=CFA+0
ebp=[CFA-8] eip=[CFA-4]

th1/fr0 supplying caller's saved ebp (6)'s location, cached
 th1/fr1 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
 th1/fr1 m_cfa = 0x114fbbc
 th1/fr1 initialized frame current pc is 0x11882d0 cfa is 0x114fbbc
th1/fr0 supplying caller's saved eip (8)'s location, cached
th1/fr0 with pc value of 0x11882d0, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882d0 cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11882d0, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882d0 cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11882d6, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882d6 cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11882dd, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882dd cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11882dd, function name is 'main'
th1/fr0 0x0000000001188064: CFA=ebp +8 => esi=[CFA-12] ebp=[CFA-8]
esp=CFA+0 eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11882dd cfa is 0x114fbbc using
assembly insn profiling UnwindPlan
th1/fr0 with pc value of 0x11906d5, no symbol/function name is known.
th1/fr0 0x00000000011906d5: CFA=ebp +8 => esp=CFA+0 ebp=[CFA-8] eip=[CFA-4]

th1/fr0 CFA is 0x114fbbc: Register ebp (6) contents are 0x114fbb4, offset
is 8
th1/fr0 initialized frame current pc is 0x11906d5 cfa is 0x114fbbc using
i386 default unwind plan UnwindPlan
th1/fr0 supplying caller's saved eip (8)'s location using i386 default
unwind plan UnwindPlan
th1/fr0 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fbb8]
 th1/fr1 pc = 0x1190a41
th1/fr0 supplying caller's saved ebp (6)'s location using i386 default
unwind plan UnwindPlan
th1/fr0 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -8 [saved at 0x114fbb4]
 th1/fr1 fp = 0x114fbfc
th1/fr0 supplying caller's saved esp (7)'s location using i386 default
unwind plan UnwindPlan
th1/fr0 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fbbc]
 th1/fr1 sp = 0x114fbbc
 th1/fr1 with pc value of 0x1190a41, no symbol/function name is known.
 th1/fr1 Backing up the pc value of 0x1190a41 by 1 and re-doing symbol
lookup; old symbol was
 th1/fr1 Symbol is now
 th1/fr1 active row: 0x0000000001190a41: CFA=ebp +8 => esp=CFA+0
ebp=[CFA-8] eip=[CFA-4]

th1/fr0 supplying caller's saved ebp (6)'s location, cached
 th1/fr1 CFA is 0x114fc04: Register ebp (6) contents are 0x114fbfc, offset
is 8
 th1/fr1 m_cfa = 0x114fc04
 th1/fr1 initialized frame current pc is 0x1190a41 cfa is 0x114fc04
th1/fr0 supplying caller's saved eip (8)'s location, cached
th1/fr0 with pc value of 0x1190a41, no symbol/function name is known.
th1/fr0 0x0000000001190a41: CFA=ebp +8 => esp=CFA+0 ebp=[CFA-8] eip=[CFA-4]

th1/fr0 CFA is 0x114fc04: Register ebp (6) contents are 0x114fbfc, offset
is 8
th1/fr0 initialized frame current pc is 0x1190a41 cfa is 0x114fc04 using
i386 default unwind plan UnwindPlan
th1/fr0 with pc value of 0x1190a41, no symbol/function name is known.
th1/fr0 0x0000000001190a41: CFA=ebp +8 => esp=CFA+0 ebp=[CFA-8] eip=[CFA-4]

th1/fr0 CFA is 0x114fc04: Register ebp (6) contents are 0x114fbfc, offset
is 8
th1/fr0 initialized frame current pc is 0x1190a41 cfa is 0x114fc04 using
i386 default unwind plan UnwindPlan
th1/fr0 supplying caller's saved eip (8)'s location using i386 default
unwind plan UnwindPlan
th1/fr0 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fc00]
 th1/fr1 pc = 0x75107c04
th1/fr0 supplying caller's saved ebp (6)'s location using i386 default
unwind plan UnwindPlan
th1/fr0 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -8 [saved at 0x114fbfc]
 th1/fr1 fp = 0x114fc10
th1/fr0 supplying caller's saved esp (7)'s location using i386 default
unwind plan UnwindPlan
th1/fr0 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc04]
 th1/fr1 sp = 0x114fc04
 th1/fr1 with pc value of 0x75107c04, symbol name is 'BaseThreadInitThunk'
 th1/fr1 active row: 0x0000000075107bf1: CFA=ebp +8 => esi=[CFA-16]
ebp=[CFA-8] esp=CFA+0 eip=[CFA-4]

th1/fr0 supplying caller's saved ebp (6)'s location, cached
 th1/fr1 CFA is 0x114fc18: Register ebp (6) contents are 0x114fc10, offset
is 8
 th1/fr1 m_cfa = 0x114fc18
 th1/fr1 initialized frame current pc is 0x75107c04 cfa is 0x114fc18
th1/fr0 supplying caller's saved eip (8)'s location, cached
 th1/fr1 supplying caller's saved eip (8)'s location using assembly insn
profiling UnwindPlan
 th1/fr1 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fc14]
  th1/fr2 pc = 0x7774b54f
 th1/fr1 supplying caller's saved ebp (6)'s location using assembly insn
profiling UnwindPlan
 th1/fr1 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -8 [saved at 0x114fc10]
  th1/fr2 fp = 0x114fc58
 th1/fr1 supplying caller's saved esp (7)'s location using assembly insn
profiling UnwindPlan
 th1/fr1 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc18]
  th1/fr2 sp = 0x114fc18
  th1/fr2 with pc value of 0x7774b54f, symbol name is
'RtlInitializeExceptionChain'
  th1/fr2 active row: 0x000000007774b504: CFA=ebp+12 => ebp=[CFA-12]
esp=CFA+0 eip=[CFA-4]

 th1/fr1 supplying caller's saved ebp (6)'s location, cached
  th1/fr2 CFA is 0x114fc64: Register ebp (6) contents are 0x114fc58, offset
is 12
  th1/fr2 m_cfa = 0x114fc64
  th1/fr2 initialized frame current pc is 0x7774b54f cfa is 0x114fc64
 th1/fr1 supplying caller's saved eip (8)'s location, cached
  th1/fr2 supplying caller's saved eip (8)'s location using assembly insn
profiling UnwindPlan
  th1/fr2 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fc60]
   th1/fr3 pc = 0xffffffff
  th1/fr2 supplying caller's saved ebp (6)'s location using assembly insn
profiling UnwindPlan
  th1/fr2 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -12 [saved at 0x114fc58]
   th1/fr3 fp = 0x114fc68
  th1/fr2 supplying caller's saved esp (7)'s location using assembly insn
profiling UnwindPlan
  th1/fr2 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc64]
   th1/fr3 sp = 0x114fc64
   th1/fr3 using architectural default unwind method
  th1/fr2 supplying caller's saved ebp (6)'s location, cached
   th1/fr3 CFA is 0x114fc70: Register ebp (6) contents are 0x114fc68,
offset is 8
   th1/fr3 initialized frame cfa is 0x114fc70
  th1/fr2 supplying caller's saved eip (8)'s location, cached
   th1/fr3 supplying caller's saved eip (8)'s location using i386 default
unwind plan UnwindPlan
   th1/fr3 supplying caller's register eip (8) from the stack, saved at CFA
plus offset -4 [saved at 0x114fc6c]
    th1/fr4 pc = 0x0
   th1/fr3 supplying caller's saved ebp (6)'s location using i386 default
unwind plan UnwindPlan
   th1/fr3 supplying caller's register ebp (6) from the stack, saved at CFA
plus offset -8 [saved at 0x114fc68]
    th1/fr4 fp = 0x0
   th1/fr3 supplying caller's saved esp (7)'s location using i386 default
unwind plan UnwindPlan
   th1/fr3 supplying caller's register esp (7), value is CFA plus offset 0
[value is 0x114fc70]
    th1/fr4 sp = 0x114fc70
    th1/fr4 this frame has a pc of 0x0
    Frame 4 invalid RegisterContext for this frame, stopping stack walk
th1 Unwind of this thread is complete.

Can you help me interepret this and figure out exactly the point at which
things are going wrong?  printf() uses a standard calling convention, so I
feel like in theory if I can identify the first location that things start
to go awry, I may just be able to bail out and have the unwinder fall back
to the architecture default unwind plan, which should work.

One more question.  The original "bt" command works, and that 0x1190a41
function (frame 1) didn't have symbols either.  Why is it able to unwind
through this function, but not through printf()?  They use the same calling
convention and there are symbols for neither one (which is another reason I
think there might be a simple fix hiding in the unwinder).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20150403/444c52de/attachment.html>


More information about the lldb-dev mailing list