Skip to content

Conversation

@kinke
Copy link
Member

@kinke kinke commented May 1, 2018

  • Add support for 64-bit DWARF.
  • Add support for DWARF v4.
  • Fix alignment issues on non-x86 architectures (DWARF data is packed).
  • Fix backtrace on Ubuntu 18.04 (DSO-relative DWARF addresses vs. absolute addresses returned by backtrace()) => probably fixes https://issues.dlang.org/show_bug.cgi?id=18068.

Testing here how codegen/exception_stack_trace.d looks like with Ubuntu 14.04; should go upstream when finished.

@kinke
Copy link
Member Author

kinke commented May 1, 2018

The existing code only reads the executable's debug_line section; line debuginfos in other shared objects aren't used. That's a problem for my current implementation, as addresses in other shared objects may be mapped to wrong line infos in the executable, e.g., backtrace with -g -link-defaultlib-debug -dwarf-version=4:

runtime.d:787 [0x55968bbfb3a8]
runtime.d:1056 [0x55968bbface8]
dmain2.d:296 [0x55968bbe02f0]
deh.d:24 [0x55968bbffe7e]
dwarfeh.d:321 [0x55968bbe0e82]
exception_stack_trace.d:6 [0x55968bbd651d]
exception_stack_trace.d:11 [0x55968bbd6528]
exception_stack_trace.d:18 [0x55968bbd653c]
dmain2.d:516 [0x55968bbe09ac]
dmain2.d:477 [0x55968bbe0789]
dmain2.d:516 [0x55968bbe08aa]
dmain2.d:477 [0x55968bbe0789]
dmain2.d:536 [0x55968bbe06c0]
__entrypoint.d:8 [0x55968bbd6694]
minfo.d:428 __libc_start_main [0x7ff04716cb96]   <== obviously not in minfo.d
??:? [0x55968bbd6389]

With additional -link-defaultlib-shared, no line infos for druntime (but exported symbol names and consequently suppressing all frames above and incl. _d_throw_exception):

exception_stack_trace.d:6 [0x5575f66cac0d]
exception_stack_trace.d:11 [0x5575f66cac18]
exception_stack_trace.d:18 [0x5575f66cac2c]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().__lambda1() [0x7f1ac5c539ac]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x7f1ac5c53789]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x7f1ac5c538aa]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x7f1ac5c53789]
??:? _d_run_main [0x7f1ac5c536c0]
__entrypoint.d:8 [0x5575f66cad84]
??:? __libc_start_main [0x7f1ac5589b96]
??:? [0x5575f66caa79]

@kinke
Copy link
Member Author

kinke commented May 1, 2018

I finally figured how to get the base address of the DSO executable (parsing /proc/self/maps, not sure how robust that is, but oh well), so the relative DWARF addresses in the executable's debug_line section can now be properly translated to absolute ones, and there are no wrong line infos for code in other DSOs anymore.

@kinke
Copy link
Member Author

kinke commented May 1, 2018

Upstream PR: dlang/druntime#2151

@kinke kinke changed the title [WIP] druntime: Try to fix rt.backtrace.dwarf druntime: Fix rt.backtrace.dwarf May 2, 2018
@kinke
Copy link
Member Author

kinke commented May 11, 2018

I'd like to merge this for 1.10, as a temporary solution for the backtrace issue with relocatable executables (e.g., on Ubuntu 18.04), as the upstream fix may not make it into 2.080. Seb has come up with an alternate solution without /proc/self/maps file parsing, plus Jacob already added upstream Mach-O support for rt.backtrace, so there'll be more changes soon anyway.

Backtrace generation on ARM etc. may also be improved by the alignment fixes.

@kinke kinke merged commit d7a1bd7 into ldc-developers:merge-2.080 May 11, 2018
@kinke kinke deleted the backtrace branch May 11, 2018 22:42
@nordlow
Copy link
Contributor

nordlow commented May 12, 2018

I just made a test program foo.d containing

void f()
{
    assert(0);
}

void g()
{
    f();
}

unittest
{
    g();
}

compiled and run as

ldmd2 -g -unittest -main foo.d && ./foo

which prints

core.exception.AssertError@foo.d(3): Assertion failure
----------------
??:? [0x55618653bece]
??:? [0x55618653f16a]
??:? [0x55618652dc9d]
??:? [0x5561865289b5]
foo.d:3 [0x5561865282b8]
foo.d:8 [0x5561865282c8]
foo.d:13 [0x5561865282d8]
??:? [0x55618653c74b]
??:? [0x556186533d81]
??:? [0x556186534399]
??:? [0x556186533d2b]
??:? [0x55618652a2ee]
??:? [0x55618653c568]
??:? [0x55618652d8ea]
??:? [0x55618652d815]
__entrypoint.d:8 [0x556186528284]
??:? __libc_start_main [0x7efd1d22bb96]
??:? [0x5561865280a9]
1/1 unittests FAILED

which means that I can now see my backtraces again. Wonderful!

One thing though...what's with the rows starting with ??:??

@kinke
Copy link
Member Author

kinke commented May 12, 2018

what's with the rows starting with ??:??

??:? means unknown file/line debuginfos. In your case, those are mostly frames in druntime, which is compiled without debuginfos. Use -link-defaultlib-debug to link against debug druntime with debuginfos.
An additional -L-export-dynamic additionally adds the function names from the dynamic symbol table, at the cost of a bigger file size; that's what DMD does by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants