[PATCH] os: use libunwind to generate backtraces
Kristian Høgsberg
krh at bitplanet.net
Mon Feb 18 09:10:04 PST 2013
On Sat, Feb 16, 2013 at 10:45 AM, Marcin Slusarz
<marcin.slusarz at 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.slusarz at 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 at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
More information about the xorg-devel
mailing list