All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Alex Bennée" <alex.bennee@linaro.org>
Subject: [RFC PATCH] util: add a qemu_backtrace utility function
Date: Mon,  1 Aug 2022 15:12:09 +0100	[thread overview]
Message-ID: <20220801141209.2184305-1-alex.bennee@linaro.org> (raw)

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 --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'))
-- 
2.30.2



                 reply	other threads:[~2022-08-01 14:14 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220801141209.2184305-1-alex.bennee@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.