[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