[igt-dev] [PATCH i-g-t] lib/core: Use libdw to decode stack trace with debugging symbols

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Tue Aug 28 12:16:36 UTC 2018


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) __igt_fail_assert:1467
  #1 (../tests/meta_test.c) test_result:95
  #2 (../tests/meta_test.c) __real_main120:137
  #3 (../tests/meta_test.c) main:120
  #4 (../csu/libc-start.c) __libc_start_main:344
  #5 [_start+0x2a]

Cc: Petri Latvala <petri.latvala at intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 configure.ac    |  1 +
 lib/Makefile.am |  2 ++
 lib/igt_core.c  | 50 ++++++++++++++++++++++++++++++++++++++++++++-----
 lib/meson.build |  1 +
 meson.build     |  1 +
 5 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 72f359943779..c75ef284f3bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,6 +128,7 @@ PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10])
 PKG_CHECK_MODULES(KMOD, [libkmod])
 PKG_CHECK_MODULES(PROCPS, [libprocps])
 PKG_CHECK_MODULES(LIBUNWIND, [libunwind])
+PKG_CHECK_MODULES(LIBDW, [libdw])
 PKG_CHECK_MODULES(SSL, [openssl])
 PKG_CHECK_MODULES(VALGRIND, [valgrind], [have_valgrind=yes], [have_valgrind=no])
 
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 6251bdb85f67..388b8b00ae36 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -60,6 +60,7 @@ AM_CFLAGS = \
 	    $(DRM_CFLAGS) \
 	    $(PCIACCESS_CFLAGS) \
 	    $(LIBUNWIND_CFLAGS) \
+	    $(LIBDW_CFLAGS) \
 	    $(GSL_CFLAGS) \
 	    $(KMOD_CFLAGS) \
 	    $(PROCPS_CFLAGS) \
@@ -86,6 +87,7 @@ libintel_tools_la_LIBADD = \
 	$(CAIRO_LIBS) \
 	$(LIBUDEV_LIBS) \
 	$(LIBUNWIND_LIBS) \
+	$(LIBDW_LIBS) \
 	$(TIMER_LIBS) \
 	$(XMLRPC_LIBS) \
 	$(LIBUDEV_LIBS) \
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 09c40af93ee1..b0a47449c7f7 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, *name;
+			Dwfl_Line *line;
+			int lineno;
+			GElf_Sym sym;
+
+			line = dwfl_module_getsrc(mod, ip);
+			name = dwfl_module_addrsym(mod, ip, &sym, NULL);
+
+			if (line && name) {
+				src = dwfl_lineinfo(line, NULL, &lineno, NULL, NULL, NULL);
+				igt_info("  #%d (%s) %s:%d\n", stack_num++, src, name, lineno);
+				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";
diff --git a/lib/meson.build b/lib/meson.build
index 6b554c681579..e60e5e02f9d0 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -60,6 +60,7 @@ lib_deps = [
 	libprocps,
 	libudev,
 	libunwind,
+	libdw,
 	pciaccess,
 	pthreads,
 	math,
diff --git a/meson.build b/meson.build
index 7278c4383624..faf1b764d69d 100644
--- a/meson.build
+++ b/meson.build
@@ -103,6 +103,7 @@ pciaccess = dependency('pciaccess', version : '>=0.10')
 libkmod = dependency('libkmod')
 libprocps = dependency('libprocps', required : true)
 libunwind = dependency('libunwind', required : true)
+libdw = dependency('libdw', required : true)
 ssl = dependency('openssl', required : true)
 
 valgrind = null_dep
-- 
2.18.0



More information about the igt-dev mailing list