]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
coredump: Include module offsets in stack traces
authorAaron Plattner <aplattner@nvidia.com>
Thu, 17 Oct 2019 19:56:15 +0000 (12:56 -0700)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 18 Oct 2019 13:26:47 +0000 (15:26 +0200)
These offsets can be useful to decode stack traces through modules that don't
have symbol names. For example, with a simple test that crashes after calling
through several static functions, systemd-coredump reports this:

 Oct 17 : Process 640333 (a.out) of user 1000 dumped core.

          Stack trace of thread 640333:
          #0  0x00005562c2b9f11d n/a (/tmp/a.out)
          #1  0x00005562c2b9f12d n/a (/tmp/a.out)
          #2  0x00005562c2b9f139 n/a (/tmp/a.out)
          #3  0x00005562c2b9f145 n/a (/tmp/a.out)
          #4  0x00007fc768b39153 __libc_start_main (libc.so.6)
          #5  0x00005562c2b9f04e n/a (/tmp/a.out)

With this change:

          Stack trace of thread 666897:
          #0  0x0000555668fbe11d n/a (/tmp/a.out + 0x111d)
          #1  0x0000555668fbe12d n/a (/tmp/a.out + 0x112d)
          #2  0x0000555668fbe139 n/a (/tmp/a.out + 0x1139)
          #3  0x0000555668fbe145 n/a (/tmp/a.out + 0x1145)
          #4  0x00007f7b5c828153 __libc_start_main (libc.so.6 + 0x27153)
          #5  0x0000555668fbe04e n/a (/tmp/a.out + 0x104e)

Disassembling the test binary shows that these offsets line up:

 0000000000001119 <crash>:
     1119:      55                      push   %rbp
     111a:      48 89 e5                mov    %rsp,%rbp
     111d:      0f 0b                   ud2                 <---- #0

 000000000000111f <b>:
     111f:      55                      push   %rbp
     1120:      48 89 e5                mov    %rsp,%rbp
     1123:      b8 00 00 00 00          mov    $0x0,%eax
     1128:      e8 ec ff ff ff          callq  1119 <crash>
     112d:      90                      nop                 <---- #1
     112e:      5d                      pop    %rbp
     112f:      c3                      retq

 0000000000001130 <a>:
     1130:      55                      push   %rbp
     1131:      48 89 e5                mov    %rsp,%rbp
     1134:      e8 e6 ff ff ff          callq  111f <b>
     1139:      90                      nop                 <---- #2
     113a:      5d                      pop    %rbp
     113b:      c3                      retq

 000000000000113c <main>:
     113c:      55                      push   %rbp
     113d:      48 89 e5                mov    %rsp,%rbp
     1140:      e8 eb ff ff ff          callq  1130 <a>
     1145:      b8 00 00 00 00          mov    $0x0,%eax    <---- #3
     114a:      5d                      pop    %rbp
     114b:      c3                      retq
     114c:      0f 1f 40 00             nopl   0x0(%rax)

 (from libc.so.6)
 0000000000027060 <__libc_start_main>:
   27060: f3 0f 1e fa           endbr64
   27064: 41 56                 push   %r14
   27066: 31 c0                 xor    %eax,%eax
   [...]
   2714c: 48 8b 44 24 18        mov    0x18(%rsp),%rax
   27151: ff d0                 callq  *%rax
   27153: 89 c7                 mov    %eax,%edi    <---- #4
   27155: e8 e6 76 01 00        callq  3e840 <exit>

src/coredump/stacktrace.c

index a962cde125b85a6baf7b0897a79a0f9fb181e071..4e0d3e76987e5a376509d7147bfaa1a1f20aebea 100644 (file)
@@ -32,6 +32,7 @@ static int frame_callback(Dwfl_Frame *frame, void *userdata) {
         const char *fname = NULL, *symbol = NULL;
         Dwfl_Module *module;
         bool is_activation;
+        uint64_t module_offset = 0;
 
         assert(frame);
         assert(c);
@@ -48,6 +49,7 @@ static int frame_callback(Dwfl_Frame *frame, void *userdata) {
         if (module) {
                 Dwarf_Die *s, *cudie;
                 int n;
+                Dwarf_Addr start;
 
                 cudie = dwfl_module_addrdie(module, pc_adjusted, &bias);
                 if (cudie) {
@@ -73,10 +75,11 @@ static int frame_callback(Dwfl_Frame *frame, void *userdata) {
                 if (!symbol)
                         symbol = dwfl_module_addrname(module, pc_adjusted);
 
-                fname = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                fname = dwfl_module_info(module, NULL, &start, NULL, NULL, NULL, NULL, NULL);
+                module_offset = pc - start;
         }
 
-        fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s)\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname));
+        fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s + 0x%" PRIx64 ")\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname), module_offset);
         c->n_frame++;
 
         return DWARF_CB_OK;