@@ -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
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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;
+}
@@ -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'))
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