diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2019-10-17 21:56:15 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-10-18 15:26:47 +0200 |
commit | ab84cf91911b54e51096c889b084a825a23a4e26 (patch) | |
tree | 0d5bb88a23d58dcb62ba86d50a0f7533b2076db0 | |
parent | test: blacklist TEST-41 on Ubuntu CI (diff) | |
download | systemd-ab84cf91911b54e51096c889b084a825a23a4e26.tar.xz systemd-ab84cf91911b54e51096c889b084a825a23a4e26.zip |
coredump: Include module offsets in stack traces
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>
-rw-r--r-- | src/coredump/stacktrace.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/src/coredump/stacktrace.c b/src/coredump/stacktrace.c index a962cde125..4e0d3e7698 100644 --- a/src/coredump/stacktrace.c +++ b/src/coredump/stacktrace.c @@ -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; |