diff mbox series

3/6] eal: support libunwind based backtrace

Message ID 20210730084938.2426128-4-jerinj@marvell.com (mailing list archive)
State Superseded
Delegated to: Thomas Monjalon
Headers show
Series 3/6] eal: support libunwind based backtrace | expand

Checks

Context Check Description
ci/Intel-compilation warning apply issues
ci/checkpatch success coding style OK

Commit Message

Jerin Jacob Kollanukkaran July 30, 2021, 8:49 a.m. UTC
From: Jerin Jacob <jerinj@marvell.com>

adding optional libwind library dependency to DPDK for
enhanced backtrace based on ucontext.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 .github/workflows/build.yml |  2 +-
 .travis.yml                 |  2 +-
 config/meson.build          |  8 +++++++
 lib/eal/unix/eal_oops.c     | 47 +++++++++++++++++++++++++++++++++++++
 4 files changed, 57 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7dac20ddeb..caaca207a6 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -93,7 +93,7 @@  jobs:
       run: sudo apt install -y ccache libnuma-dev python3-setuptools
         python3-wheel python3-pip python3-pyelftools ninja-build libbsd-dev
         libpcap-dev libibverbs-dev libcrypto++-dev libfdt-dev libjansson-dev
-        libarchive-dev
+        libarchive-dev libunwind-dev
     - name: Install libabigail build dependencies if no cache is available
       if: env.ABI_CHECKS == 'true' && steps.libabigail-cache.outputs.cache-hit != 'true'
       run: sudo apt install -y autoconf automake libtool pkg-config libxml2-dev
diff --git a/.travis.yml b/.travis.yml
index 23067d9e3c..e72b156014 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,7 @@  addons:
     packages: &required_packages
       - [libnuma-dev, python3-setuptools, python3-wheel, python3-pip, python3-pyelftools, ninja-build]
       - [libbsd-dev, libpcap-dev, libibverbs-dev, libcrypto++-dev, libfdt-dev, libjansson-dev]
-      - [libarchive-dev]
+      - [libarchive-dev, libunwind-dev]
 
 _aarch64_packages: &aarch64_packages
   - *required_packages
diff --git a/config/meson.build b/config/meson.build
index e80421003b..26a85dab6b 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -236,6 +236,14 @@  if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false
     dpdk_extra_ldflags += '-latomic'
 endif
 
+# check for libunwind
+unwind_dep = dependency('libunwind', required: false, method: 'pkg-config')
+if unwind_dep.found() and cc.has_header('libunwind.h', dependencies: unwind_dep)
+    dpdk_conf.set('RTE_USE_LIBUNWIND', 1)
+    add_project_link_arguments('-lunwind', language: 'c')
+    dpdk_extra_ldflags += '-lunwind'
+endif
+
 # add -include rte_config to cflags
 add_project_arguments('-include', 'rte_config.h', language: 'c')
 
diff --git a/lib/eal/unix/eal_oops.c b/lib/eal/unix/eal_oops.c
index 1120c8ad8c..118b236f35 100644
--- a/lib/eal/unix/eal_oops.c
+++ b/lib/eal/unix/eal_oops.c
@@ -25,6 +25,50 @@  struct oops_signal {
 
 static struct oops_signal signals_db[RTE_DIM(oops_signals)];
 
+#if defined(RTE_USE_LIBUNWIND)
+
+#define BACKTRACE_DEPTH 256
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+
+static void
+back_trace_dump(ucontext_t *context)
+{
+	unw_cursor_t cursor;
+	unw_word_t ip, off;
+	int rc, level = 0;
+	char name[256];
+
+	if (context == NULL) {
+		rte_dump_stack();
+		return;
+	}
+
+	rc = unw_init_local(&cursor, (unw_context_t *)context);
+	if (rc < 0)
+		goto fail;
+
+	for (;;) {
+		rc = unw_get_reg(&cursor, UNW_REG_IP, &ip);
+		if (rc < 0)
+			goto fail;
+		rc = unw_get_proc_name(&cursor, name, sizeof(name), &off);
+		if (rc == 0)
+			oops_print("[%16p]: %s()+0x%" PRIx64 "\n", (void *)ip,
+				   name, (uint64_t)off);
+		else
+			oops_print("[%16p]: <unknown>\n", (void *)ip);
+		rc = unw_step(&cursor);
+		if (rc <= 0 || ++level >= BACKTRACE_DEPTH)
+			break;
+	}
+	return;
+fail:
+	oops_print("libunwind call failed %s\n", unw_strerror(rc));
+}
+
+#else
+
 static void
 back_trace_dump(ucontext_t *context)
 {
@@ -32,6 +76,9 @@  back_trace_dump(ucontext_t *context)
 
 	rte_dump_stack();
 }
+
+#endif
+
 static void
 siginfo_dump(int sig, siginfo_t *info)
 {