[PATCH] D46628: [ELF] Add --strip-debug-non-line option

Brian Gesiak via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 22 18:36:03 PDT 2018


modocache added a comment.

Sorry for letting this languish a bit. I took some time to experiment. Long story short I think `llvm-dwarfdump` and `lldb` aren't able to verify this option at the moment.

In https://reviews.llvm.org/D46628#1094011, @modocache wrote:

> As for validating the debug info, what about using 'llvm-dwarfdump -verify'? In fact running that on the output of this new option resulted in errors, so I'll address those.


It turns out that **both** `gold --strip-debug-non-line` and the implementation of `ld.lld --strip-debug-non-line` in this patch output debug info that (1) `llvm-dwarfdump -verify` reports errors with, and (2) causes SIGSEVs in lldb.

I'll demonstrate with program `bar.cpp`:

  #include <stdexcept>
  
  void foo() {
    throw std::exception();
  }
  
  int main() {
    foo();
  }

Compiling and linking this program with Clang trunk and GNU gold version 2.25.1 results in invalid DWARF info, according to `llvm-dwarfdump`:

  $ clang++ bar.cpp -g -fuse-ld=gold -Xlinker --strip-debug-non-line -o bar-gold-strip-debug-non-line
  $ llvm-dwarfdump -verify bar-gold-strip-debug-non-line
  Verifying bar-gold-strip-debug-non-line:        file format ELF64-x86-64
  Verifying .debug_abbrev...
  Verifying .debug_info Unit Header Chain...
  error: DW_AT_ranges offset is beyond .debug_ranges bounds:
  
  0x0000000b: DW_TAG_compile_unit
                DW_AT_producer    ("clang version 7.0.0 (http://llvm.org/git/clang.git 1aad2818adcb106eb0b350c8c9028b75a055647e) (http://llvm.org/git/llvm.git e7343867622e65294892168ec85edf426e5c3430)")
                DW_AT_language    (DW_LANG_C_plus_plus)
                DW_AT_name        ("bar.cpp")
                DW_AT_stmt_list   (0x00000000)
                DW_AT_comp_dir    ("/data/users/bgesiak/Source/fb/llvm/build")
                DW_AT_GNU_pubnames        (true)
                DW_AT_low_pc      (0x0000000000000000)
                DW_AT_ranges      (0x00000000)
  
  Verifying .debug_info references...
  Errors detected.

The exact same error occurs with this patch:

  $ clang++ bar.cpp -g -fuse-ld=lld -Xlinker --strip-debug-non-line -o bar-lld-strip-debug-non-line
  $ llvm-dwarfdump -verify bar-lld-strip-debug-non-line
  Verifying bar-lld-strip-debug-non-line: file format ELF64-x86-64
  Verifying .debug_abbrev...
  Verifying .debug_info Unit Header Chain...
  error: DW_AT_ranges offset is beyond .debug_ranges bounds:
  
  0x0000000b: DW_TAG_compile_unit
                DW_AT_producer    ("clang version 7.0.0 (http://llvm.org/git/clang.git 1aad2818adcb106eb0b350c8c9028b75a055647e) (http://llvm.org/git/llvm.git e7343867622e65294892168ec85edf426e5c3430)")
                DW_AT_language    (DW_LANG_C_plus_plus)
                DW_AT_name        ("bar.cpp")
                DW_AT_stmt_list   (0x00000000)
                DW_AT_comp_dir    ("/data/users/bgesiak/Source/fb/llvm/build")
                DW_AT_GNU_pubnames        (true)
                DW_AT_low_pc      (0x0000000000000000)
                DW_AT_ranges      (0x00000000)
  
  Verifying .debug_info references...
  Errors detected.

I think `llvm-dwarfdump` points to a legitimate error in both of these cases, because when I attempt to use lldb trunk to place a breakpoint in the program, lldb crashes:

  $ lldb -- bar-gold-strip-debug-non-line
  (lldb) target create "bar-gold-strip-debug-non-line"
  Current executable set to 'bar-gold-strip-debug-non-line' (x86_64).
  (lldb) b main
  Stack dump:
  0.      HandleCommand(command = "b main")
  1.      HandleCommand(command = "breakpoint set --name 'main'")
  fish: “bin/lldb -- bar-gold-strip-debu…” terminated by signal SIGSEGV (Address boundary error)
  
  $ lldb -- bar-lld-strip-debug-non-line
  (lldb) target create "bar-lld-strip-debug-non-line"
  Current executable set to 'bar-lld-strip-debug-non-line' (x86_64).
  (lldb) b main
  Stack dump:
  0.      HandleCommand(command = "b main")
  1.      HandleCommand(command = "breakpoint set --name 'main'")
  fish: “bin/lldb -- bar-lld-strip-debug…” terminated by signal SIGSEGV (Address boundary error)

gdb works just fine with both of these programs, however. It doesn't print line numbers in its backtrace, even if the program is linked with gold, like I would have expected. But the line numbers are still present in the debug info, and symbolizers like this one <https://github.com/facebook/folly/tree/master/folly/experimental/symbolizer> are capable of producing stack traces with those line numbers included.

In https://reviews.llvm.org/D46628#1094613, @aprantl wrote:

> If dwarfdump can't find a problem with the output (and there is a problem with it) then that's a bug in dwarfdump. If you want to do functional testing, you'll probably want to pipe the result through something like llvm-symbolizer or lldb as an end-to-end test.


On the contrary, it turns out that `llvm-dwarfdump` does find problems with the output, and if crashing lldb is any indication, there are actually problems with the output -- both with this patch, and with gold. Would the correct next step to be to patch lldb and llvm-dwarfdump? Is there something else I've neglected to consider? Feedback welcome!


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D46628





More information about the llvm-commits mailing list