Bug when presenting stacktraces

Hi all,

I'm having a heisenbug in a program that uses lldb. I've implemented a simple repl (much like Driver.cpp). My problem is that sometimes the stack traces are very weird and don't agree with 'register read rip'.

Example:
(lldb) bt
* thread #1: tid = 0x2503, 0x00007fff6dd1226a dyld`_ZL18gdb_image_notifier15dyld_image_modejPK15dyld_image_info + 1, stop reason = breakpoint 1.1
frame #0: 0x00007fff6dd1226a dyld`_ZL18gdb_image_notifier15dyld_image_modejPK15dyld_image_info + 1
frame #1: 0x00007fff8ddf8570 libsystem_notify.dylib
(lldb) register read rip
rip = 0x000000010e107824 tests`main + 36 at tests.c:15

Frame #0 says the rip should be near 0x00007fff6dd1226a, but register read rip yields 0x000000010e107824.

Disassembling the address from frame #0, I have:
(lldb) disassemble -C 20 -s 0x00007fff6dd1226a
dyld`_ZL18gdb_image_notifier15dyld_image_modejPK15dyld_image_info + 1:
0x7fff6dd1226a: movq %rsp, %rbp
0x7fff6dd1226d: popq %rbp
0x7fff6dd1226e: ret
dyld`setAlImageInfosHalt(char const*, unsigned long):
0x7fff6dd1226f: pushq %rbp
0x7fff6dd12270: movq %rsp, %rbp
0x7fff6dd12273: movq %rdi, 178894(%rip) ; dyld_all_image_infos + 56, dyld_all_image_infos + 56
0x7fff6dd1227a: movq %rsi, 178895(%rip) ; dyld_all_image_infos + 64, dyld_all_image_infos + 64
0x7fff6dd12281: popq %rbp
0x7fff6dd12282: ret
dyld`removeImageFromAllImages(mach_header const*):
0x7fff6dd12283: pushq %rbp
0x7fff6dd12284: movq %rsp, %rbp
0x7fff6dd12287: pushq %rbx

But if I step over one instruction:
(lldb) register read rip
rip = 0x000000010e107824 tests`main + 36 at tests.c:15
(lldb) si
Process 30849 stopped
* thread #1: tid = 0x2503, 0x000000010e108540 tests`atoi at atoi.c:9, stop reason = instruction step into
frame #0: 0x000000010e108540 tests`atoi at atoi.c:9

It manages to catch up with the real address and function, stepping into a call to the (home-made) atoi function.

Is this a known bug? I can't reproduce it yet (it just happens, sometimes). If I manage to find out why this is happening, I'll ping back the list.

Just to make sure there are no mistakes: I have not seen this problem in Driver.cpp. Only in my program (that mimics most of Driver.cpp's structure and calls).

Any ideas?

Thanks,

  Filipe

Hi all,

I'm having a heisenbug in a program that uses lldb. I've implemented a simple repl (much like Driver.cpp). My problem is that sometimes the stack traces are very weird and don't agree with 'register read rip'.

Example:
(lldb) bt
* thread #1: tid = 0x2503, 0x00007fff6dd1226a dyld`_ZL18gdb_image_notifier15dyld_image_modejPK15dyld_image_info + 1, stop reason = breakpoint 1.1
frame #0: 0x00007fff6dd1226a dyld`_ZL18gdb_image_notifier15dyld_image_modejPK15dyld_image_info + 1
frame #1: 0x00007fff8ddf8570 libsystem_notify.dylib
(lldb) register read rip
rip = 0x000000010e107824 tests`main + 36 at tests.c:15

Frame #0 says the rip should be near 0x00007fff6dd1226a, but register read rip yields 0x000000010e107824.

Disassembling the address from frame #0, I have:
(lldb) disassemble -C 20 -s 0x00007fff6dd1226a
dyld`_ZL18gdb_image_notifier15dyld_image_modejPK15dyld_image_info + 1:
0x7fff6dd1226a: movq %rsp, %rbp
0x7fff6dd1226d: popq %rbp
0x7fff6dd1226e: ret
dyld`setAlImageInfosHalt(char const*, unsigned long):
0x7fff6dd1226f: pushq %rbp
0x7fff6dd12270: movq %rsp, %rbp
0x7fff6dd12273: movq %rdi, 178894(%rip) ; dyld_all_image_infos + 56, dyld_all_image_infos + 56
0x7fff6dd1227a: movq %rsi, 178895(%rip) ; dyld_all_image_infos + 64, dyld_all_image_infos + 64
0x7fff6dd12281: popq %rbp
0x7fff6dd12282: ret
dyld`removeImageFromAllImages(mach_header const*):
0x7fff6dd12283: pushq %rbp
0x7fff6dd12284: movq %rsp, %rbp
0x7fff6dd12287: pushq %rbx

But if I step over one instruction:
(lldb) register read rip
rip = 0x000000010e107824 tests`main + 36 at tests.c:15
(lldb) si
Process 30849 stopped
* thread #1: tid = 0x2503, 0x000000010e108540 tests`atoi at atoi.c:9, stop reason = instruction step into
frame #0: 0x000000010e108540 tests`atoi at atoi.c:9

It manages to catch up with the real address and function, stepping into a call to the (home-made) atoi function.

Is this a known bug? I can't reproduce it yet (it just happens, sometimes). If I manage to find out why this is happening, I'll ping back the list.

Just to make sure there are no mistakes: I have not seen this problem in Driver.cpp. Only in my program (that mimics most of Driver.cpp's structure and calls).

Any ideas?

If I can see your code, I might be able to explain why this is happening. This shouldn't be able to happen, but we have seen some odd behaviour when trying to add python breakpoint scripts, which might be similar to what you are running into. For example if you do:

(lldb) breakpoint set --name printf
(lldb) breakpoint command add -s python

print frame
thread = frame.GetThread()
frame.GetThread().StepOver()
new_frame = thread.GetFrameAtIndex(0)
print new_frame
DONE

As a reminder, the function prototype for a python breakpoint command callback function is "def bp_hit_callback (frame, bp_loc)" so the commands above are run as:

def bp_hit_callback (frame, bp_loc):
    print frame
    thread = frame.GetThread()
    frame.GetThread().StepOver()
    new_frame = thread.GetFrameAtIndex(0)
    print new_frame

In this case we are seeing that the new_frame is often the same as the old frame.

Greg Clayton