[Mesa-dev] [PATCH 2/2] gallium/util: libunwind support

Nicolai Hähnle nhaehnle at gmail.com
Tue Mar 28 14:50:03 UTC 2017


On 24.03.2017 22:21, 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.

I'm not familiar with libunwind, but this does look reasonable to me, 
and would certainly be a nice improvement where it's used. Series is

Acked-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

>
> Signed-off-by: Rob Clark <robdclark at gmail.com>
> ---
>  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,
>


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list