Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Support demangling for D symbols via dlopen #3

Closed
wants to merge 1 commit into from

Conversation

timotheecour
Copy link

@timotheecour timotheecour commented Feb 27, 2018

the shared library that is dlopen'd is defined separately in https://github.com/timotheecour/dtools/blob/master/dtools/lldbdplugin.d

before:

(lldb) bt
error: need to add support for DW_TAG_base_type 'immutable(char)' encoded with DW_ATE = 0x10, bit_size = 8
error: need to add support for DW_TAG_base_type 'char' encoded with DW_ATE = 0x10, bit_size = 8
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000100000cd0 test TIMBREAK at foo/test2.d:3
    frame #1: 0x0000000100000e60 test _D4test3funFiZv(a=11) + 128 at test.d:11
    frame #2: 0x0000000100000ec7 test _D4test__T4fun1TiZQiFiZv(a=11) + 23 at test.d:16
    frame #3: 0x0000000100000e8c test _Dmain(args=string[] @ 0x00007ffeefbfcec8) + 28 at test.d:20
    frame #4: 0x000000010014d80f test _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 15
    frame #5: 0x000000010014d74e test _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 14
    frame #6: 0x000000010014d652 test _d_run_main + 466
    frame #7: 0x00000001000019b5 test main(argc=1, argv=0x00007ffeefbfd028) + 37 at __entrypoint.d:8
    frame #8: 0x00007fff7279f115 libdyld.dylib start + 1
    frame #9: 0x00007fff7279f115 libdyld.dylib start + 1
(lldb)

after:

(lldb) bt
error: need to add support for DW_TAG_base_type 'immutable(char)' encoded with DW_ATE = 0x10, bit_size = 8
error: need to add support for DW_TAG_base_type 'char' encoded with DW_ATE = 0x10, bit_size = 8
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000100000cd0 test TIMBREAK at foo/test2.d:3
    frame #1: 0x0000000100000e60 test void test.fun(a=11) + 128 at test.d:11
    frame #2: 0x0000000100000ec7 test void test.fun1!(a=11).fun1(int) + 23 at test.d:16
    frame #3: 0x0000000100000e8c test _Dmain(args=string[] @ 0x00007ffeefbfce68) + 28 at test.d:20
    frame #4: 0x000000010014d80f test void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().__lambda1() + 15
    frame #5: 0x000000010014d74e test void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) + 14
    frame #6: 0x000000010014d652 test _d_run_main + 466
    frame #7: 0x00000001000019b5 test main(argc=1, argv=0x00007ffeefbfcfc8) + 37 at __entrypoint.d:8
    frame #8: 0x00007fff7279f115 libdyld.dylib start + 1
    frame #9: 0x00007fff7279f115 libdyld.dylib start + 1

limitations:

  • breakpoint on fully qualified names work, eg: b test.fun but not on templates, eg: b test.fun1
  • can be slow for large programs, but not sure why (even if the plugin is modified to be a noop, the lldb I compile is still 5X slower than a homebrew version of lldb)

addresses issue https://issues.dlang.org/show_bug.cgi?id=817

OSX: symbols mangled on gdb,ggdb,cgdb,lldb but not on ubuntu; no line numbers on stacktraces

@sylvestre
Copy link
Collaborator

I am sorry but we don't use github...
Please report patches on:
https://reviews.llvm.org/

@sylvestre sylvestre closed this Feb 27, 2018
@timotheecour
Copy link
Author

timotheecour commented Mar 9, 2018

moved to: https://reviews.llvm.org/D44321
(after running arc diff master)

dtzWill pushed a commit that referenced this pull request Apr 18, 2018
Normally, LLDB is creating a high-fidelity representation of a live
process, including a list of modules and sections, with the 
associated memory address ranges. In order to build the module and
section map LLDB tries to locate the local module image (object file)
and will parse it.

This does not work for postmortem debugging scenarios where the crash
dump (minidump in this case) was captured on a different machine.

Fortunately the minidump format encodes enough information about
each module's memory range to allow us to create placeholder modules.
This enables most LLDB functionality involving address-to-module
translations.

Also, we may want to completly disable the search for matching
local object files if we load minidumps unless we can prove that the
local image matches the one from the crash origin.
(not part of this change, see: llvm.org/pr35193)

Example: Identify the module from a stack frame PC:

Before:
  thread #1, stop reason = Exception 0xc0000005 encountered at address 0x164d14
    frame #0: 0x00164d14
    frame #1: 0x00167c79
    frame #2: 0x00167e6d
    frame #3: 0x7510336a
    frame #4: 0x77759882
    frame #5: 0x77759855

After:
  thread #1, stop reason = Exception 0xc0000005 encountered at address 0x164d14
    frame #0: 0x00164d14 C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug\fizzbuzz.exe
    frame #1: 0x00167c79 C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug\fizzbuzz.exe
    frame #2: 0x00167e6d C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug\fizzbuzz.exe
    frame #3: 0x7510336a C:\Windows\SysWOW64\kernel32.dll
    frame #4: 0x77759882 C:\Windows\SysWOW64\ntdll.dll
    frame #5: 0x77759855 C:\Windows\SysWOW64\ntdll.dll

Example: target modules list

Before:
error: the target has no associated executable images

After:
[ 0] C:\Windows\System32\MSVCP120D.dll 
[ 1] C:\Windows\SysWOW64\kernel32.dll 
[ 2] C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug\fizzbuzz.exe 
[ 3] C:\Windows\System32\MSVCR120D.dll 
[ 4] C:\Windows\SysWOW64\KERNELBASE.dll 
[ 5] C:\Windows\SysWOW64\ntdll.dll

NOTE: the minidump format also includes the debug info GUID, so we can
fill-in the module UUID from it, but this part was excluded from this change
to keep the changes simple (the LLDB UUID is hardcoded to be either 16 or
20 bytes, while the CodeView GUIDs are normally 24 bytes)

Differential Revision: https://reviews.llvm.org/D45700



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@330302 91177308-0d34-0410-b5e6-96231b3b80d8
dtzWill pushed a commit that referenced this pull request May 2, 2019
logging messages that are written the same, making it difficult to
know for certain which code path was taken based on a logfile.  Add
some words to make each unique.

Right now the ordering for finding a FullUnwindPlan (ignoring
fallback unwind plan logic) is

1. If this is a _sigtramp like function, try eh_frame which is
   hand written on darwin systems to account for finding the
   saved register context correctly.

2. Ask the DynamicLoader if eh_frame should be preferred for
   this frame.  Some binaries on the system may have hand-written
   eh_frame and the DynamicLoader is the source for this.  (primarily
   this is for hand-written assembly in the objc runtime, and we tell
   lldb to trust that for functions in libobjc.dylib.)

3. if 0th frame, use GetUnwindPlanAtNonCallSite plan.

4. GetUnwindPlanAtCallSite {for 0th or any other}

5. GetUnwindPlanAtNonCallSite {now for non-0th frames, only if not from a compiler? hm.}

6. GetUnwindPlanArchitectureDefaultAtFunctionEntry if we're on the first instruction

7. Architectural default unwind plan ABI::CreateDefaultUnwindPlan


I'm moving #6 -- DefaultAtFunctionEntry -- up to between #3 and #4,
where we're already doing things specific to the zeroth frame.  If
we're on the zeroth frame and the GetUnwindPlanAtNonCallSite plan
has failed for some reason, and we're on the first instruction, we
should definitely use DefaultAtFunctionEntry instead of any other
unwind plan.  If we're trying to step out of some rando function
on the system that we couldn't assembly instruction inspect, this
is sufficient for us to step out of it.




git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@359847 91177308-0d34-0410-b5e6-96231b3b80d8
dtzWill pushed a commit that referenced this pull request Jul 1, 2019
This fixes a failing testcase on Fedora 30 x86_64 (regression Fedora 29->30):

PASS:
./bin/lldb ./lldb-test-build.noindex/functionalities/unwind/noreturn/TestNoreturnUnwind.test_dwarf/a.out -o 'settings set symbols.enable-external-lookup false' -o r -o bt -o quit
  * frame #0: 0x00007ffff7aa6e75 libc.so.6`__GI_raise + 325
    frame #1: 0x00007ffff7a91895 libc.so.6`__GI_abort + 295
    frame #2: 0x0000000000401140 a.out`func_c at main.c:12:2
    frame #3: 0x000000000040113a a.out`func_b at main.c:18:2
    frame #4: 0x0000000000401134 a.out`func_a at main.c:26:2
    frame #5: 0x000000000040112e a.out`main(argc=<unavailable>, argv=<unavailable>) at main.c:32:2
    frame #6: 0x00007ffff7a92f33 libc.so.6`__libc_start_main + 243
    frame #7: 0x000000000040106e a.out`_start + 46

vs.

FAIL - unrecognized abort() function:
./bin/lldb ./lldb-test-build.noindex/functionalities/unwind/noreturn/TestNoreturnUnwind.test_dwarf/a.out -o 'settings set symbols.enable-external-lookup false' -o r -o bt -o quit
  * frame #0: 0x00007ffff7aa6e75 libc.so.6`.annobin_raise.c + 325
    frame #1: 0x00007ffff7a91895 libc.so.6`.annobin_loadmsgcat.c_end.unlikely + 295
    frame #2: 0x0000000000401140 a.out`func_c at main.c:12:2
    frame #3: 0x000000000040113a a.out`func_b at main.c:18:2
    frame #4: 0x0000000000401134 a.out`func_a at main.c:26:2
    frame #5: 0x000000000040112e a.out`main(argc=<unavailable>, argv=<unavailable>) at main.c:32:2
    frame #6: 0x00007ffff7a92f33 libc.so.6`.annobin_libc_start.c + 243
    frame #7: 0x000000000040106e a.out`.annobin_init.c.hot + 46

The extra ELF symbols are there due to Annobin (I did not investigate why this problem happened specifically since F-30 and not since F-28).
It is due to:

Symbol table '.dynsym' contains 2361 entries:
Valu e          Size Type   Bind   Vis     Name
0000000000022769   5 FUNC   LOCAL  DEFAULT _nl_load_domain.cold
000000000002276e   0 NOTYPE LOCAL  HIDDEN  .annobin_abort.c.unlikely
...
000000000002276e   0 NOTYPE LOCAL  HIDDEN  .annobin_loadmsgcat.c_end.unlikely
...
000000000002276e   0 NOTYPE LOCAL  HIDDEN  .annobin_textdomain.c_end.unlikely
000000000002276e 548 FUNC   GLOBAL DEFAULT abort
000000000002276e 548 FUNC   GLOBAL DEFAULT abort@@GLIBC_2.2.5
000000000002276e 548 FUNC   LOCAL  DEFAULT __GI_abort
0000000000022992   0 NOTYPE LOCAL  HIDDEN  .annobin_abort.c_end.unlikely

Differential Revision: https://reviews.llvm.org/D63540


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@364773 91177308-0d34-0410-b5e6-96231b3b80d8
dtzWill pushed a commit that referenced this pull request Oct 7, 2019
Summary:
If the .symtab section is stripped from the binary it might be that
there's a .gnu_debugdata section which contains a smaller .symtab in
order to provide enough information to create a backtrace with function
names or to set and hit a breakpoint on a function name.

This change looks for a .gnu_debugdata section in the ELF object file.
The .gnu_debugdata section contains a xz-compressed ELF file with a
.symtab section inside. Symbols from that compressed .symtab section
are merged with the main object file's .dynsym symbols (if any).
In addition we always load the .dynsym even if there's a .symtab
section.

For example, the Fedora and RHEL operating systems strip their binaries
but keep a .gnu_debugdata section. While gdb already can read this
section, LLDB until this patch couldn't. To test this patch on a
Fedora or RHEL operating system, try to set a breakpoint on the "help"
symbol in the "zip" binary. Before this patch, only GDB can set this
breakpoint; now LLDB also can do so without installing extra debug
symbols:

    lldb /usr/bin/zip -b -o "b help" -o "r" -o "bt" -- -h

The above line runs LLDB in batch mode and on the "/usr/bin/zip -h"
target:

    (lldb) target create "/usr/bin/zip"
    Current executable set to '/usr/bin/zip' (x86_64).
    (lldb) settings set -- target.run-args  "-h"

Before the program starts, we set a breakpoint on the "help" symbol:

    (lldb) b help
    Breakpoint 1: where = zip`help, address = 0x00000000004093b0

Once the program is run and has hit the breakpoint we ask for a
backtrace:

    (lldb) r
    Process 10073 stopped
    * thread #1, name = 'zip', stop reason = breakpoint 1.1
        frame #0: 0x00000000004093b0 zip`help
    zip`help:
    ->  0x4093b0 <+0>:  pushq  %r12
        0x4093b2 <+2>:  movq   0x2af5f(%rip), %rsi       ;  + 4056
        0x4093b9 <+9>:  movl   $0x1, %edi
        0x4093be <+14>: xorl   %eax, %eax

    Process 10073 launched: '/usr/bin/zip' (x86_64)
    (lldb) bt
    * thread #1, name = 'zip', stop reason = breakpoint 1.1
      * frame #0: 0x00000000004093b0 zip`help
        frame #1: 0x0000000000403970 zip`main + 3248
        frame #2: 0x00007ffff7d8bf33 libc.so.6`__libc_start_main + 243
        frame #3: 0x0000000000408cee zip`_start + 46

In order to support the .gnu_debugdata section, one has to have LZMA
development headers installed. The CMake section, that controls this
part looks for the LZMA headers and enables .gnu_debugdata support by
default if they are found; otherwise or if explicitly requested, the
minidebuginfo support is disabled.

GDB supports the "mini debuginfo" section .gnu_debugdata since v7.6
(2013).

Reviewers: espindola, labath, jankratochvil, alexshap

Reviewed By: labath

Subscribers: rnkovacs, wuzish, shafik, emaste, mgorny, arichardson, hiraditya, MaskRay, lldb-commits

Tags: #lldb, #llvm

Differential Revision: https://reviews.llvm.org/D66791

git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@373891 91177308-0d34-0410-b5e6-96231b3b80d8
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants