summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2019-10-17 21:56:15 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-10-18 15:26:47 +0200
commitab84cf91911b54e51096c889b084a825a23a4e26 (patch)
tree0d5bb88a23d58dcb62ba86d50a0f7533b2076db0
parenttest: blacklist TEST-41 on Ubuntu CI (diff)
downloadsystemd-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.c7
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;