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],
#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
fprintf(f, "%s\n", symbol);
}
}
+
+#endif /* HAVE_LIBUNWIND */