On Sat, Feb 16, 2013 at 10:45 AM, Marcin Slusarz <marcin.slus...@gmail.com> wrote: > Libunwind generates backtraces much more reliably than glibc's "backtrace".
Wow, didn't know about libunwind, it looks amazing. Do you mind if port this and use in weston? Kristian > Signed-off-by: Marcin Slusarz <marcin.slus...@gmail.com> > --- > configure.ac | 7 +++++ > include/dix-config.h.in | 3 +++ > os/Makefile.am | 5 ++++ > os/backtrace.c | 70 > +++++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 85 insertions(+) > > diff --git a/configure.ac b/configure.ac > index 9415a54..4a292da 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -309,6 +309,13 @@ AC_CHECK_HEADER([execinfo.h],[ > ])] > ) > > +PKG_CHECK_MODULES(LIBUNWIND, libunwind, [HAVE_LIBUNWIND=yes], > [HAVE_LIBUNWIND=no]) > +if test "x$HAVE_LIBUNWIND" = xyes; then > + AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support]) > +fi > +AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes]) > + > + > dnl > --------------------------------------------------------------------------- > dnl Bus options and CPU capabilities. Replaces logic in > dnl hw/xfree86/os-support/bus/Makefile.am, among others. > diff --git a/include/dix-config.h.in b/include/dix-config.h.in > index 578f249..5102263 100644 > --- a/include/dix-config.h.in > +++ b/include/dix-config.h.in > @@ -60,6 +60,9 @@ > /* Has backtrace support */ > #undef HAVE_BACKTRACE > > +/* Has libunwind support */ > +#undef HAVE_LIBUNWIND > + > /* Define to 1 if you have the <byteswap.h> header file. */ > #undef HAVE_BYTESWAP_H > > diff --git a/os/Makefile.am b/os/Makefile.am > index 8891485..364b6da 100644 > --- a/os/Makefile.am > +++ b/os/Makefile.am > @@ -34,6 +34,11 @@ if XDMCP > libos_la_SOURCES += $(XDMCP_SRCS) > endif > > +if HAVE_LIBUNWIND > +AM_CFLAGS += $(LIBUNWIND_CFLAGS) > +libos_la_LIBADD += $(LIBUNWIND_LIBS) > +endif > + > EXTRA_DIST = $(SECURERPC_SRCS) $(XDMCP_SRCS) > > if SPECIAL_DTRACE_OBJECTS > diff --git a/os/backtrace.c b/os/backtrace.c > index daac60c..02aeb03 100644 > --- a/os/backtrace.c > +++ b/os/backtrace.c > @@ -30,6 +30,75 @@ > #include <errno.h> > #include <string.h> > > +#ifdef HAVE_LIBUNWIND > + > +#define UNW_LOCAL_ONLY > +#include <libunwind.h> > + > +#ifndef _GNU_SOURCE > +#define _GNU_SOURCE > +#endif > +#include <dlfcn.h> > + > +void > +xorg_backtrace(void) > +{ > + unw_cursor_t cursor; > + unw_context_t context; > + unw_word_t off; > + unw_proc_info_t pip; > + int ret, i = 0; > + char procname[256]; > + const char *filename; > + Dl_info dlinfo; > + > + pip.unwind_info = NULL; > + ret = unw_getcontext(&context); > + if (ret) { > + ErrorFSigSafe("unw_getcontext: %d\n", ret); > + return; > + } > + > + ret = unw_init_local(&cursor, &context); > + if (ret) { > + ErrorFSigSafe("unw_init_local: %d\n", ret); > + return; > + } > + > + ErrorFSigSafe("\n"); > + ErrorFSigSafe("Backtrace:\n"); > + ret = unw_step(&cursor); > + while (ret > 0) { > + ret = unw_get_proc_info(&cursor, &pip); > + if (ret) { > + ErrorFSigSafe("unw_get_proc_info: %d\n", ret); > + break; > + } > + > + ret = unw_get_proc_name(&cursor, procname, 256, &off); > + if (ret && ret != -UNW_ENOMEM) { > + if (ret != -UNW_EUNSPEC) > + ErrorFSigSafe("unw_get_proc_name: %d\n", ret); > + procname[0] = '?'; > + procname[1] = 0; > + } > + > + if (dladdr((void *)(pip.start_ip + off), &dlinfo) && > dlinfo.dli_fname && > + *dlinfo.dli_fname) > + filename = dlinfo.dli_fname; > + else > + filename = "?"; > + > + ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname, > + ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip > + off)); > + > + ret = unw_step(&cursor); > + if (ret < 0) > + ErrorFSigSafe("unw_step: %d\n", ret); > + } > + ErrorFSigSafe("\n"); > +} > +#else > #ifdef HAVE_BACKTRACE > #ifndef _GNU_SOURCE > #define _GNU_SOURCE > @@ -246,3 +315,4 @@ xorg_backtrace(void) > > #endif > #endif > +#endif > -- > 1.8.1 > > _______________________________________________ > xorg-devel@lists.x.org: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel