[Mesa-dev] [PATCH] gallium/util: Provide a backup backtrace implementation v3
Thomas Hellstrom
thellstrom at vmware.com
Tue Apr 4 09:26:27 UTC 2017
The default GCC implementation works only for i386 and the new
libunwind implementation is very slow at capturing backtraces which makes
it unusable together with the u_debug_flush functionality, which is also
why we make the user have to explicitly select libunwind if needed.
The check for availability is the same as the one previously implemented in
u_debug_symbol.c
v2:
- Adjust libunwind selection
- Check for CALLOC failure
- If the call chain is short, make sure the backtrace buffer is populated
with NULL function pointers
v3:
- Really adjust libunwind selection
Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
---
configure.ac | 7 ++-----
src/gallium/auxiliary/util/u_debug_stack.c | 32 ++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/configure.ac b/configure.ac
index 83cd5d1..da39e0b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1044,14 +1044,11 @@ dnl libunwind
dnl
AC_ARG_ENABLE([libunwind],
[AS_HELP_STRING([--enable-libunwind],
- [Use libunwind for backtracing (default: auto)])],
+ [Use libunwind for backtracing (default: no)])],
[LIBUNWIND="$enableval"],
- [LIBUNWIND="auto"])
+ [LIBUNWIND="no"])
PKG_CHECK_MODULES(LIBUNWIND, libunwind, [HAVE_LIBUNWIND=yes], [HAVE_LIBUNWIND=no])
-if test "x$LIBUNWIND" = "xauto"; then
- LIBUNWIND="$HAVE_LIBUNWIND"
-fi
if test "x$LIBUNWIND" = "xyes"; then
if test "x$HAVE_LIBUNWIND" != "xyes"; then
diff --git a/src/gallium/auxiliary/util/u_debug_stack.c b/src/gallium/auxiliary/util/u_debug_stack.c
index cf05f13..e265832 100644
--- a/src/gallium/auxiliary/util/u_debug_stack.c
+++ b/src/gallium/auxiliary/util/u_debug_stack.c
@@ -35,6 +35,7 @@
#include "u_debug.h"
#include "u_debug_symbol.h"
#include "u_debug_stack.h"
+#include "u_memory.h"
#if defined(HAVE_LIBUNWIND)
@@ -137,6 +138,36 @@ debug_backtrace_print(FILE *f,
* not to break it down in smaller functions to avoid adding new frames to the
* calling stack.
*/
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+
+#include <execinfo.h>
+
+void
+debug_backtrace_capture(struct debug_stack_frame *bt,
+ unsigned start_frame,
+ unsigned nr_frames)
+{
+ int ret = 0;
+ unsigned i;
+
+ void **buffer = CALLOC(start_frame + nr_frames, sizeof(*buffer));
+
+ if (buffer)
+ ret = backtrace(buffer, start_frame + nr_frames);
+
+ for (i = 0; i < nr_frames; ++i) {
+ if (start_frame + i >= ret)
+ bt[i].function = NULL;
+ else
+ bt[i].function = buffer[start_frame + i];
+ }
+
+ if (buffer)
+ FREE(buffer);
+}
+
+#else /* defined(__GLIBC__) && !defined(__UCLIBC__) */
+
void
debug_backtrace_capture(struct debug_stack_frame *backtrace,
unsigned start_frame,
@@ -237,6 +268,7 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace,
}
}
+#endif /* !(defined(__GLIBC__) && !defined(__UCLIBC__)) */
void
debug_backtrace_dump(const struct debug_stack_frame *backtrace,
--
2.5.0
More information about the mesa-dev
mailing list