diff mbox series

[RFC] util: add a qemu_backtrace utility function

Message ID 20220801141209.2184305-1-alex.bennee@linaro.org
State New
Headers show
Series [RFC] util: add a qemu_backtrace utility function | expand

Commit Message

Alex Bennée Aug. 1, 2022, 2:12 p.m. UTC
When debugging failures in CI which can't be replicated locally it can
be useful to dump a backtrace. However ad-hoc debug code is likely to
fail to compile on numerous hosts so lets package up a utility
function with proper compiler detection.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 configure                | 29 +++++++++++++++++++++++++++++
 include/qemu/backtrace.h | 28 ++++++++++++++++++++++++++++
 util/backtrace.c         | 37 +++++++++++++++++++++++++++++++++++++
 util/meson.build         |  1 +
 4 files changed, 95 insertions(+)
 create mode 100644 include/qemu/backtrace.h
 create mode 100644 util/backtrace.c
diff mbox series

Patch

diff --git a/configure b/configure
index 2c19329d58..e3482fc3f6 100755
--- a/configure
+++ b/configure
@@ -1828,6 +1828,27 @@  EOF
   fi
 fi
 
+##########################################
+# check for backtrace support
+
+have_backtrace=no
+
+cat > $TMPC << EOF
+#include <execinfo.h>
+#include <stdio.h>
+int main(void) {
+    int nptrs;
+    void *buffer[100];
+
+    nptrs = backtrace(buffer, 100);
+    printf("backtrace() returned %d addresses\n", nptrs);
+}
+EOF
+
+if compile_prog "$CPU_CFLAGS -rdynamic" ""; then
+    have_backtrace=yes
+fi
+
 ##########################################
 # check for slirp
 
@@ -2276,6 +2297,10 @@  if test "$have_ubsan" = "yes"; then
   QEMU_CFLAGS="-fsanitize=undefined $QEMU_CFLAGS"
   QEMU_LDFLAGS="-fsanitize=undefined $QEMU_LDFLAGS"
 fi
+if test "$have_backtrace" = "yes" ; then
+  QEMU_CFLAGS="-rdynamic $QEMU_CFLAGS"
+  QEMU_LDFLAGS="-rdynamic $QEMU_LDFLAGS"
+fi
 
 ##########################################
 
@@ -2480,6 +2505,10 @@  if test "$have_tsan" = "yes" && test "$have_tsan_iface_fiber" = "yes" ; then
     echo "CONFIG_TSAN=y" >> $config_host_mak
 fi
 
+if test "$have_backtrace" = "yes" ; then
+    echo "CONFIG_BACKTRACE=y" >> $config_host_mak
+fi
+
 if test "$plugins" = "yes" ; then
     echo "CONFIG_PLUGIN=y" >> $config_host_mak
 fi
diff --git a/include/qemu/backtrace.h b/include/qemu/backtrace.h
new file mode 100644
index 0000000000..5888081b83
--- /dev/null
+++ b/include/qemu/backtrace.h
@@ -0,0 +1,28 @@ 
+/*
+ * Backtrace Functions
+ *
+ * Copyright (c) 2022 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _BACKTRACE_H_
+#define _BACKTRACE_H_
+
+#ifdef CONFIG_BACKTRACE
+/**
+ * qemu_backtrace() - return a backtrace of current thread
+ * max: maximum number of lines of backtrace
+ *
+ * Return an allocated GString containing the backtrace of the current
+ * thread. Caller frees the GString once done.
+ */
+GString *qemu_backtrace(int max);
+#else
+static inline GString *qemu_backtrace(int max)
+{
+    return NULL;
+}
+#endif
+
+#endif /* _BACKTRACE_H_ */
diff --git a/util/backtrace.c b/util/backtrace.c
new file mode 100644
index 0000000000..880232a0b0
--- /dev/null
+++ b/util/backtrace.c
@@ -0,0 +1,37 @@ 
+/*
+ * Backtrace abstraction to gloss over the differences between architectures.
+ *
+ * Copyright (c) 2022 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/backtrace.h"
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define BT_BUF_SIZE 128
+
+GString *qemu_backtrace(int max)
+{
+    int nptrs;
+    void *buffer[BT_BUF_SIZE];
+    char **strings;
+    GString *res = g_string_new("");
+
+    nptrs = backtrace(buffer, BT_BUF_SIZE);
+    strings = backtrace_symbols(buffer, nptrs);
+    if (strings == NULL) {
+        g_string_printf(res, "Failed to extract symbols");
+    } else {
+        for (int j = 0; j < MIN(max, nptrs); j++) {
+            g_string_append_printf(res, "%s\n", strings[j]);
+        }
+        free(strings);
+    }
+
+    return res;
+}
diff --git a/util/meson.build b/util/meson.build
index 5e282130df..abad5a5377 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -55,6 +55,7 @@  util_ss.add(files('guest-random.c'))
 util_ss.add(files('yank.c'))
 util_ss.add(files('int128.c'))
 util_ss.add(files('memalign.c'))
+util_ss.add(when: 'CONFIG_BACKTRACE', if_true: files('backtrace.c'))
 
 if have_user
   util_ss.add(files('selfmap.c'))