[Mesa-dev] [PATCH] gallium/util: Provide a backup backtrace implementation v2

Thomas Hellstrom thellstrom at vmware.com
Tue Apr 4 09:08:57 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.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
---
 src/gallium/auxiliary/util/u_debug_stack.c | 32 ++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

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