Commit 70c27200 authored by Rob Clark's avatar Rob Clark

gallium/util: libunwind support

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's avatarRob Clark <robdclark@gmail.com>
Acked-by: 's avatarNicolai Hähnle <nicolai.haehnle@amd.com>
parent c3c884c4
......@@ -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],
......
......@@ -46,6 +46,7 @@ GALLIUM_TARGET_CFLAGS = \
GALLIUM_COMMON_LIB_DEPS = \
-lm \
$(LIBUNWIND_LIBS) \
$(LIBSENSORS_LIBS) \
$(CLOCK_LIB) \
$(PTHREAD_LIBS) \
......
......@@ -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 */
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment