summaryrefslogtreecommitdiff
path: root/lib/igt_core.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2018-08-28 14:04:25 +0200
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2018-08-30 11:10:36 +0200
commite39e09910fc8e369e24f6a0cabaeb9356dbfae08 (patch)
tree7e62bc1522651571296d373c03479f059dd2d702 /lib/igt_core.c
parent45f0ba252194c24175b38181eb8cc3c2a6c20587 (diff)
lib/core: Use libdw to decode stack trace with debugging symbols, v2.
libdw is a new dependency built from the elfutils package. It provides us a way to generate line numbers and file names from the instruction pointer. elfutils is LGPLv3 or GPLv2, so it's ok to link against it. Before: IGT-Version: 1.23-g8ae86abd419d (x86_64) (Linux: 4.16.0-1-amd64 x86_64) Starting subtest: fail-result (meta_test:29661) CRITICAL: Test assertion failure function test_result, file ../tests/meta_test.c:94: (meta_test:29661) CRITICAL: Failed assertion: result == 1 (meta_test:29661) CRITICAL: error: 0 != 1 Stack trace: #0 [__igt_fail_assert+0x20a] #1 [test_result+0x7a] #2 [__real_main120+0x240] #3 [main+0x4a] #4 (../csu/libc-start.c) __libc_start_main:344 #5 [_start+0x2a] After: IGT-Version: 1.23-g8ae86abd419d (x86_64) (Linux: 4.16.0-1-amd64 x86_64) Starting subtest: fail-result (meta_test:1357) CRITICAL: Test assertion failure function test_result, file ../tests/meta_test.c:94: (meta_test:1357) CRITICAL: Failed assertion: result == 1 (meta_test:1357) CRITICAL: error: 0 != 1 Stack trace: #0 ../lib/igt_core.c:1467 __igt_fail_assert() #1 ../tests/meta_test.c:95 test_result() #2 ../tests/meta_test.c:137 __real_main120() #3 ../tests/meta_test.c:120 main() #4 ../csu/libc-start.c:344 __libc_start_main() #5 [_start+0x2a] Changes since v1: - Add libdw dependency to readme. - Change backtrace format slightly. Cc: Petri Latvala <petri.latvala@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> [mlankhorst: Add description about libdw in commit msg, name -> dwfl_name] Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'lib/igt_core.c')
-rw-r--r--lib/igt_core.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/lib/igt_core.c b/lib/igt_core.c
index c52c0818..23bb858f 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -73,6 +73,7 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
+#include <elfutils/libdwfl.h>
#ifdef HAVE_LIBGEN_H
#include <libgen.h> /* for basename() on Solaris */
@@ -1212,20 +1213,59 @@ static void print_backtrace(void)
unw_context_t uc;
int stack_num = 0;
+ Dwfl_Callbacks cbs = {
+ .find_elf = dwfl_linux_proc_find_elf,
+ .find_debuginfo = dwfl_standard_find_debuginfo,
+ };
+
+ Dwfl *dwfl = dwfl_begin(&cbs);
+
+ if (dwfl_linux_proc_report(dwfl, getpid())) {
+ dwfl_end(dwfl);
+ dwfl = NULL;
+ } else
+ dwfl_report_end(dwfl, NULL, NULL);
+
igt_info("Stack trace:\n");
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
while (unw_step(&cursor) > 0) {
char name[255];
- unw_word_t off;
+ unw_word_t off, ip;
+ Dwfl_Module *mod = NULL;
- if (unw_get_proc_name(&cursor, name, 255, &off) < 0)
- strcpy(name, "<unknown>");
+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
+
+ if (dwfl)
+ mod = dwfl_addrmodule(dwfl, ip);
- igt_info(" #%d [%s+0x%x]\n", stack_num++, name,
- (unsigned int) off);
+ if (mod) {
+ const char *src, *dwfl_name;
+ Dwfl_Line *line;
+ int lineno;
+ GElf_Sym sym;
+
+ line = dwfl_module_getsrc(mod, ip);
+ dwfl_name = dwfl_module_addrsym(mod, ip, &sym, NULL);
+
+ if (line && dwfl_name) {
+ src = dwfl_lineinfo(line, NULL, &lineno, NULL, NULL, NULL);
+ igt_info(" #%d %s:%d %s()\n", stack_num++, src, lineno, dwfl_name);
+ continue;
+ }
+ }
+
+ if (unw_get_proc_name(&cursor, name, 255, &off) < 0)
+ igt_info(" #%d [<unknown>+0x%x]\n", stack_num++,
+ (unsigned int) ip);
+ else
+ igt_info(" #%d [%s+0x%x]\n", stack_num++, name,
+ (unsigned int) off);
}
+
+ if (dwfl)
+ dwfl_end(dwfl);
}
static const char hex[] = "0123456789abcdef";