[lldb-dev] strange issues on linux

Ryan Brown ribrdb at google.com
Thu May 28 17:43:43 PDT 2015


I'm running into some issues trying to debug with lldb on linux.
It started with errors that debugserver aborted. I ran lldb-server manually
and then used process connect, and got this error:

lldb-server:
../tools/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp:227:
virtual NativeRegisterContextSP
lldb_private::process_linux::NativeThreadLinux::GetRegisterContext():
Assertion `reg_interface && "OS or CPU not supported!"' failed.

I synced lldb and llvm to head and rebuilt, and this error went away. But
then later it showed up again on a different machine when debugging the
same binary with the newly built lldb.

Once I get the binary running under lldb I'm seeing strange things on my
OperatingSystem plugin. Sometimes things work normally, sometimes the OS
plugin seems to see incorrect register values but they're correct at the
lldb prompt, and sometimes the registers just seem completely wrong.
The behaviour is pretty consistent when I set a breakpoint at the same
line, but if I move it to a different line or move to a different machine
I'll get a different behavior.

Here's an example where the plugin sees invalid registers:
(lldb) run
OperatingSystemGo::UpdateThreadList(0, 1, 1) fetching thread data from Go
for pid 678
Process 678 launched: 'vc.test' (x86_64)
I0528 17:09:01.105108     678 rand.go:86] Seeding pseudo-random number
generator with 1432858141105104474
OperatingSystemGo::UpdateThreadList(1, 1, 1) fetching thread data from Go
for pid 678
OperatingSystemGo: RealThread 0 has sp 7fffffffd430
Process 678 stopped
* thread #1: tid = 0x02a6, 0x000000000049f379
vc.test`vc.createVCs(~r0=stream.XVC at 0x000000c208030668, ~r1=stream.XVC
at 0x000000c208030678) + 73 at xvc_test.go:23, name =
'vc.test', stop reason = breakpoint 1.1
    frame #0: 0x000000000049f379 vc.test`vc.createVCs(~r0=stream.XVC at
0x000000c208030668, ~r1=stream.XVC at 0x000000c208030678) + 73 at
xvc_test.go:23
(lldb) register read
General Purpose Registers:
       rax = 0x000000c208030580
       rbx = 0x0000000000000000
       rcx = 0x000000c208001a40
       rdx = 0x000000000095e678  vc.test`vc.TestXVC.f
       rdi = 0x0000000000000000
       rsi = 0x000000c208030768
       rbp = 0x0000000000abe578  main.statictmp_0002 + 312
       rsp = 0x000000c208030500
        r8 = 0x000000005567ae1d
        r9 = 0x0000000000000007
       r10 = 0x000000000300c146
       r11 = 0x000000000000007b
       r12 = 0x0000000000000025
       r13 = 0x000000000095d840  vc.test`runtime.gcbits.3082880518
       r14 = 0x0000000000000008
       r15 = 0x0000000000000000
       rip = 0x000000000049f379  vc.test`vc.createVCs + 73 at xvc_test.go:23
    rflags = 0x0000000000000246
        cs = 0x0000000000000033
        fs = 0x0000000000000000
        gs = 0x0000000000000000
        ss = 0x000000000000002b
        ds = 0x0000000000000000
        es = 0x0000000000000000

So my plugin sees one real thread, but the SP is bogus: 7fffffffd430
When I print registers at the prompt i get the correct value:
0x000000c208030500

Then I run stepi:

(lldb) stepi
OperatingSystemGo::UpdateThreadList(8, 3, 3) fetching thread data from Go
for pid 678
OperatingSystemGo: RealThread 0 has sp c2080304f8
OperatingSystemGo: RealThread 1 has sp 7ffff77f5df8
OperatingSystemGo: RealThread 2 has sp 7ffff6fb4d70

Now my plugin is getting three threads. But we've only gone one
instruction, so where are these other threads coming from? Thread 0 has the
correct SP this time, but not the other threads.
Now that we've got the right SP value, the OS plugin is able to find the
memory thread which confuses the threadplan so it keeps running till it
hits a breakpoint:

OperatingSystemGo::UpdateThreadList(9, 3, 3) fetching thread data from Go
for pid 678
OperatingSystemGo: RealThread 0 has sp c208030500
OperatingSystemGo: RealThread 1 has sp 7ffff77f5df8
OperatingSystemGo: RealThread 2 has sp 7ffff6fb4d70
Process 678 stopped
* thread #8: tid = 0x0006, 0x000000000049f3b1
vc.test`vc.createVCs(~r0=stream.XVC at 0x000000c208030668, ~r1=stream.XVC
at 0x000000c208030678) + 129 at xvc_test.go:24, stop reason = breakpoint 2.1
    frame #0: 0x000000000049f3b1 vc.test`vc.createVCs(~r0=stream.XVC at
0x000000c208030668, ~r1=stream.XVC at 0x000000c208030678) + 129 at
xvc_test.go:24
(lldb)

Debugging the same binary on a different machine with the same lldb binary,
I get different behavior:

(lldb) r
There is a running process, kill it and restart?: [Y/n] y
Process 127429 exited with status = 9 (0x00000009)
OperatingSystemGo::UpdateThreadList(0, 1, 1) fetching thread data from Go
for pid 127449
Process 127449 launched: 'vc.test' (x86_64)
I0528 17:10:43.950815  127449 rand.go:86] Seeding pseudo-random number
generator with 1432858243950810731
OperatingSystemGo::UpdateThreadList(1, 1, 1) fetching thread data from Go
for pid 127449
OperatingSystemGo: RealThread 0 has sp 7fffffffde50
Process 127449 stopped
* thread #1: tid = 0x1f1d9, 0x00007ffff7ddb2d0, name = 'vc.test', stop
reason = signal SIGSTOP
    frame #0: 0x00007ffff7ddb2d0
->  0x7ffff7ddb2d0: movq   %rsp, %rdi
    0x7ffff7ddb2d3: callq  0x7ffff7ddea70
    0x7ffff7ddb2d8: movq   %rax, %r12
    0x7ffff7ddb2db: movl   0x221b17(%rip), %eax
(lldb) register read
General Purpose Registers:
       rax = 0x0000000000000000
       rbx = 0x0000000000000000
       rcx = 0x0000000000000000
       rdx = 0x0000000000000000
       rdi = 0x0000000000000000
       rsi = 0x0000000000000000
       rbp = 0x0000000000000000
       rsp = 0x00007fffffffde50
        r8 = 0x0000000000000000
        r9 = 0x0000000000000000
       r10 = 0x0000000000000000
       r11 = 0x0000000000000000
       r12 = 0x0000000000000000
       r13 = 0x0000000000000000
       r14 = 0x0000000000000000
       r15 = 0x0000000000000000
       rip = 0x00007ffff7ddb2d0
    rflags = 0x0000000000000200
        cs = 0x0000000000000033
        fs = 0x0000000000000000
        gs = 0x0000000000000000
        ss = 0x000000000000002b
        ds = 0x0000000000000000
        es = 0x0000000000000000

(lldb) bt
* thread #1: tid = 0x1f1d9, 0x00007ffff7ddb2d0, name = 'vc.test', stop
reason = signal SIGSTOP
  * frame #0: 0x00007ffff7ddb2d0


This time the plugin gets the invalid register values, but when lldb stops
at the prompt things are still invalid. The rip is garbage, so lldb doesn't
recognize that it's hit a breakpoint and the backtrace is wrong.

Any ideas what could be going on here, or how I can debug this?

-- Ryan Brown
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20150528/1a00d1a5/attachment.html>


More information about the lldb-dev mailing list