Hi, Rob, On 03/24/2017 10:21 PM, Rob Clark wrote: > It's kinda sad that (a) we don't have debug_backtrace support on !X86 > and that (b) we re-invent our own crude backtrace support in the first > place. If available, use libunwind instead. The backtrace format is > based on what xserver and weston use, since it is nice not to have to > figure out a different format. > > Signed-off-by: Rob Clark <robdcl...@gmail.com>
Did you consider glibc "backtrace()", I think it's also available on ARM... Also is the output format the same as before, or at least compatible with gallium/tools/addr2line.sh? Thanks, Thomas > --- > configure.ac | 24 ++++++++ > src/gallium/Automake.inc | 1 + > src/gallium/auxiliary/util/u_debug_stack.c | 91 > ++++++++++++++++++++++++++++++ > src/gallium/auxiliary/util/u_debug_stack.h | 15 ++++- > 4 files changed, 129 insertions(+), 2 deletions(-) > > diff --git a/configure.ac b/configure.ac > index a99684b..5046acb 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -1025,6 +1025,30 @@ AC_SUBST([LLVM_LIBS]) > AC_SUBST([LLVM_LDFLAGS]) > AC_SUBST([LLVM_INCLUDEDIR]) > > +dnl > +dnl libunwind > +dnl > +AC_ARG_ENABLE([libunwind], > + [AS_HELP_STRING([--enable-libunwind], > + [Use libunwind for backtracing (default: auto)])], > + [LIBUNWIND="$enableval"], > + [LIBUNWIND="auto"]) > + > +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 > + AC_MSG_ERROR([libunwind requested but not installed.]) > + fi > + AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support]) > +fi > + > +AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$LIBUNWIND" = xyes]) > + > + > dnl Options for APIs > AC_ARG_ENABLE([opengl], > [AS_HELP_STRING([--disable-opengl], > diff --git a/src/gallium/Automake.inc b/src/gallium/Automake.inc > index a01fa54..48b5a44 100644 > --- a/src/gallium/Automake.inc > +++ b/src/gallium/Automake.inc > @@ -46,6 +46,7 @@ GALLIUM_TARGET_CFLAGS = \ > > GALLIUM_COMMON_LIB_DEPS = \ > -lm \ > + $(LIBUNWIND_LIBS) \ > $(LIBSENSORS_LIBS) \ > $(CLOCK_LIB) \ > $(PTHREAD_LIBS) \ > diff --git a/src/gallium/auxiliary/util/u_debug_stack.c > b/src/gallium/auxiliary/util/u_debug_stack.c > index f941234..cf05f13 100644 > --- a/src/gallium/auxiliary/util/u_debug_stack.c > +++ b/src/gallium/auxiliary/util/u_debug_stack.c > @@ -36,6 +36,95 @@ > #include "u_debug_symbol.h" > #include "u_debug_stack.h" > > +#if defined(HAVE_LIBUNWIND) > + > +#ifndef _GNU_SOURCE > +#define _GNU_SOURCE > +#endif > +#include <dlfcn.h> > + > +void > +debug_backtrace_capture(struct debug_stack_frame *backtrace, > + unsigned start_frame, > + unsigned nr_frames) > +{ > + unw_cursor_t cursor; > + unw_context_t context; > + unw_proc_info_t pip; > + unsigned i = 0; > + int ret; > + > + pip.unwind_info = NULL; > + > + unw_getcontext(&context); > + unw_init_local(&cursor, &context); > + > + while ((start_frame > 0) && (unw_step(&cursor) > 0)) > + start_frame--; > + > + while (unw_step(&cursor) > 0) { > + char procname[256]; > + const char *filename; > + unw_word_t off; > + Dl_info dlinfo; > + > + unw_get_proc_info(&cursor, &pip); > + > + ret = unw_get_proc_name(&cursor, procname, 256, &off); > + if (ret && ret != -UNW_ENOMEM) { > + procname[0] = '?'; > + procname[1] = 0; > + } > + > + if (dladdr((void *)(uintptr_t)(pip.start_ip + off), &dlinfo) && > dlinfo.dli_fname && > + *dlinfo.dli_fname) > + filename = dlinfo.dli_fname; > + else > + filename = "?"; > + > + snprintf(backtrace[i].buf, sizeof(backtrace[i].buf), > + "%u: %s (%s%s+0x%x) [%p]", i, filename, procname, > + ret == -UNW_ENOMEM ? "..." : "", (int)off, > + (void *)(uintptr_t)(pip.start_ip + off)); > + > + i++; > + } > + > + while (i < nr_frames) { > + backtrace[i].buf[0] = '\0'; > + i++; > + } > +} > + > +void > +debug_backtrace_dump(const struct debug_stack_frame *backtrace, > + unsigned nr_frames) > +{ > + unsigned i; > + > + for (i = 0; i < nr_frames; ++i) { > + if (backtrace[i].buf[0] == '\0') > + break; > + debug_printf("\t%s\n", backtrace[i].buf); > + } > +} > + > +void > +debug_backtrace_print(FILE *f, > + const struct debug_stack_frame *backtrace, > + unsigned nr_frames) > +{ > + unsigned i; > + > + for (i = 0; i < nr_frames; ++i) { > + if (backtrace[i].buf[0] == '\0') > + break; > + fprintf(f, "\t%s\n", backtrace[i].buf); > + } > +} > + > +#else /* ! HAVE_LIBUNWIND */ > + > #if defined(PIPE_OS_WINDOWS) > #include <windows.h> > #endif > @@ -179,3 +268,5 @@ debug_backtrace_print(FILE *f, > fprintf(f, "%s\n", symbol); > } > } > + > +#endif /* HAVE_LIBUNWIND */ > diff --git a/src/gallium/auxiliary/util/u_debug_stack.h > b/src/gallium/auxiliary/util/u_debug_stack.h > index 04eba08..0effcbe 100644 > --- a/src/gallium/auxiliary/util/u_debug_stack.h > +++ b/src/gallium/auxiliary/util/u_debug_stack.h > @@ -30,6 +30,11 @@ > > #include <stdio.h> > > +#ifdef HAVE_LIBUNWIND > +#define UNW_LOCAL_ONLY > +#include <libunwind.h> > +#endif > + > /** > * @file > * Stack backtracing. > @@ -46,15 +51,21 @@ extern "C" { > /** > * Represent a frame from a stack backtrace. > * > - * XXX: Do not change this. > +#if defined(PIPE_OS_WINDOWS) && !defined(HAVE_LIBUNWIND) > + * XXX: Do not change this. (passed to Windows' CaptureStackBackTrace()) > +#endif > * > * TODO: This should be refactored as a void * typedef. > */ > struct debug_stack_frame > { > +#ifdef HAVE_LIBUNWIND > + char buf[128]; > +#else > const void *function; > +#endif > }; > - > + > > void > debug_backtrace_capture(struct debug_stack_frame *backtrace, _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev