<p><br>
21 lut 2013 00:37, "Peter Hutterer" <<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.net</a>> napisał(a):<br>
><br>
> On Tue, Feb 19, 2013 at 09:29:03PM +0100, Marcin Slusarz wrote:<br>
> [...]<br>
> > ---<br>
> > From: Marcin Slusarz <<a href="mailto:marcin.slusarz@gmail.com">marcin.slusarz@gmail.com</a>><br>
> > Subject: [PATCH] os: use libunwind to generate backtraces<br>
> ><br>
> > Libunwind generates backtraces much more reliably than glibc's "backtrace".<br>
> ><br>
> > Before:<br>
> > 0: /opt/xserver/bin/X (0x400000+0x18ce36) [0x58ce36]<br>
> > 1: /opt/xserver/bin/X (xorg_backtrace+0x9) [0x58d119]<br>
> > 2: /opt/xserver/bin/X (0x400000+0x190d69) [0x590d69]<br>
> > 3: /lib64/libpthread.so.0 (0x7fb904268000+0x10a90) [0x7fb904278a90]<br>
> > 4: /lib64/libc.so.6 (ioctl+0x7) [0x7fb902fbf987]<br>
> > 5: /usr/lib64/libdrm.so.2 (drmIoctl+0x28) [0x7fb90405ffa8]<br>
> > 6: /usr/lib64/libdrm.so.2 (drmCommandWrite+0x1b) [0x7fb90406235b]<br>
> > 7: /usr/lib64/libdrm_nouveau.so.2 (nouveau_bo_wait+0x89) [0x7fb902009719]<br>
> > 8: /opt/xserver/lib/xorg/modules/drivers/nouveau_drv.so (0x7fb90220e000+0x76f3) [0x7fb9022156f3]<br>
> > 9: /opt/xserver/lib/xorg/modules/libexa.so (0x7fb9019c7000+0xbae0) [0x7fb9019d2ae0]<br>
> > 10: /opt/xserver/bin/X (0x400000+0x17d2b3) [0x57d2b3]<br>
> > 11: /opt/xserver/bin/X (0x400000+0xc9930) [0x4c9930]<br>
> > 12: /opt/xserver/bin/X (0x400000+0x3a81a) [0x43a81a]<br>
> > 13: /opt/xserver/bin/X (0x400000+0x3d6a1) [0x43d6a1]<br>
> > 14: /opt/xserver/bin/X (0x400000+0x2c2ca) [0x42c2ca]<br>
> > 15: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x7fb902f019b5]<br>
> > 16: /opt/xserver/bin/X (0x400000+0x2c60d) [0x42c60d]<br>
> > 17: ?? [0x0]<br>
> ><br>
> > After:<br>
> > 0: /opt/xserver/bin/X (OsSigHandler+0x39) [0x590d69]<br>
> > 1: /lib64/libpthread.so.0 (__restore_rt+0x0) [0x7fb904278a8f]<br>
> > 2: /lib64/libc.so.6 (ioctl+0x7) [0x7fb902fbf987]<br>
> > 3: /usr/lib64/libdrm.so.2 (drmIoctl+0x28) [0x7fb90405ffa8]<br>
> > 4: /usr/lib64/libdrm.so.2 (drmCommandWrite+0x1b) [0x7fb90406235b]<br>
> > 5: /usr/lib64/libdrm_nouveau.so.2 (nouveau_bo_wait+0x89) [0x7fb902009719]<br>
> > 6: /opt/xserver/lib/xorg/modules/drivers/nouveau_drv.so (nouveau_exa_download_from_screen+0x1a3) [0x7fb9022156f3]<br>
> > 7: /opt/xserver/lib/xorg/modules/libexa.so (exaGetImage+0x1f0) [0x7fb9019d2ae0]<br>
> > 8: /opt/xserver/bin/X (miSpriteGetImage+0x173) [0x57d2b3]<br>
> > 9: /opt/xserver/bin/X (compGetImage+0xb0) [0x4c9930]<br>
> > 10: /opt/xserver/bin/X (ProcGetImage+0x55a) [0x43a81a]<br>
> > 11: /opt/xserver/bin/X (Dispatch+0x341) [0x43d6a1]<br>
> > 12: /opt/xserver/bin/X (main+0x3ba) [0x42c2ca]<br>
> > 13: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x7fb902f019b5]<br>
> > 14: /opt/xserver/bin/X (_start+0x29) [0x42c60d]<br>
> > 15: ? (?+0x29) [0x29]<br>
> ><br>
> > Signed-off-by: Marcin Slusarz <<a href="mailto:marcin.slusarz@gmail.com">marcin.slusarz@gmail.com</a>><br>
> > ---<br>
> >  <a href="http://configure.ac">configure.ac</a>            |  7 +++++<br>
> >  include/<a href="http://dix-config.h.in">dix-config.h.in</a> |  3 ++<br>
> >  os/Makefile.am          |  5 ++++<br>
> >  os/backtrace.c          | 75 +++++++++++++++++++++++++++++++++++++++++++++++++<br>
> >  4 files changed, 90 insertions(+)<br>
> ><br>
> > diff --git a/<a href="http://configure.ac">configure.ac</a> b/<a href="http://configure.ac">configure.ac</a><br>
> > index 9415a54..4a292da 100644<br>
> > --- a/<a href="http://configure.ac">configure.ac</a><br>
> > +++ b/<a href="http://configure.ac">configure.ac</a><br>
> > @@ -309,6 +309,13 @@ AC_CHECK_HEADER([execinfo.h],[<br>
> >      ])]<br>
> >  )<br>
> ><br>
> > +PKG_CHECK_MODULES(LIBUNWIND, libunwind, [HAVE_LIBUNWIND=yes], [HAVE_LIBUNWIND=no])<br>
> > +if test "x$HAVE_LIBUNWIND" = xyes; then<br>
> > +     AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support])<br>
> > +fi<br>
> > +AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes])<br>
> > +<br>
> > +<br>
> >  dnl ---------------------------------------------------------------------------<br>
> >  dnl Bus options and CPU capabilities.  Replaces logic in<br>
> >  dnl hw/xfree86/os-support/bus/Makefile.am, among others.<br>
> > diff --git a/include/<a href="http://dix-config.h.in">dix-config.h.in</a> b/include/<a href="http://dix-config.h.in">dix-config.h.in</a><br>
> > index 578f249..5102263 100644<br>
> > --- a/include/<a href="http://dix-config.h.in">dix-config.h.in</a><br>
> > +++ b/include/<a href="http://dix-config.h.in">dix-config.h.in</a><br>
> > @@ -60,6 +60,9 @@<br>
> >  /* Has backtrace support */<br>
> >  #undef HAVE_BACKTRACE<br>
> ><br>
> > +/* Has libunwind support */<br>
> > +#undef HAVE_LIBUNWIND<br>
> > +<br>
> >  /* Define to 1 if you have the <byteswap.h> header file. */<br>
> >  #undef HAVE_BYTESWAP_H<br>
> ><br>
> > diff --git a/os/Makefile.am b/os/Makefile.am<br>
> > index 8891485..364b6da 100644<br>
> > --- a/os/Makefile.am<br>
> > +++ b/os/Makefile.am<br>
> > @@ -34,6 +34,11 @@ if XDMCP<br>
> >  libos_la_SOURCES += $(XDMCP_SRCS)<br>
> >  endif<br>
> ><br>
> > +if HAVE_LIBUNWIND<br>
> > +AM_CFLAGS += $(LIBUNWIND_CFLAGS)<br>
> > +libos_la_LIBADD += $(LIBUNWIND_LIBS)<br>
> > +endif<br>
> > +<br>
> >  EXTRA_DIST = $(SECURERPC_SRCS) $(XDMCP_SRCS)<br>
> ><br>
> >  if SPECIAL_DTRACE_OBJECTS<br>
> > diff --git a/os/backtrace.c b/os/backtrace.c<br>
> > index daac60c..426f9b1 100644<br>
> > --- a/os/backtrace.c<br>
> > +++ b/os/backtrace.c<br>
> > @@ -30,6 +30,80 @@<br>
> >  #include <errno.h><br>
> >  #include <string.h><br>
> ><br>
> > +#ifdef HAVE_LIBUNWIND<br>
> > +<br>
> > +#define UNW_LOCAL_ONLY<br>
> > +#include <libunwind.h><br>
> > +<br>
> > +#ifndef _GNU_SOURCE<br>
> > +#define _GNU_SOURCE<br>
> > +#endif<br>
> > +#include <dlfcn.h><br>
> > +<br>
> > +void<br>
> > +xorg_backtrace(void)<br>
> > +{<br>
> > +    unw_cursor_t cursor;<br>
> > +    unw_context_t context;<br>
> > +    unw_word_t off;<br>
> > +    unw_proc_info_t pip;<br>
> > +    int ret, i = 0;<br>
> > +    char procname[256];<br>
> > +    const char *filename;<br>
> > +    Dl_info dlinfo;<br>
> > +<br>
> > +    pip.unwind_info = NULL;<br>
> > +    ret = unw_getcontext(&context);<br>
> > +    if (ret) {<br>
> > +        ErrorFSigSafe("unw_getcontext failed: %s [%d]\n", unw_strerror(ret),<br>
> > +                ret);<br>
> > +        return;<br>
> > +    }<br>
> > +<br>
> > +    ret = unw_init_local(&cursor, &context);<br>
> > +    if (ret) {<br>
> > +        ErrorFSigSafe("unw_init_local failed: %s [%d]\n", unw_strerror(ret),<br>
> > +                ret);<br>
> > +        return;<br>
> > +    }<br>
> > +<br>
> > +    ErrorFSigSafe("\n");<br>
> > +    ErrorFSigSafe("Backtrace:\n");<br>
> > +    ret = unw_step(&cursor);<br>
> > +    while (ret > 0) {<br>
> > +        ret = unw_get_proc_info(&cursor, &pip);<br>
> > +        if (ret) {<br>
> > +            ErrorFSigSafe("unw_get_proc_info failed: %s [%d]\n",<br>
> > +                    unw_strerror(ret), ret);<br>
> > +            break;<br>
> > +        }<br>
> > +<br>
> > +        ret = unw_get_proc_name(&cursor, procname, 256, &off);<br>
> > +        if (ret && ret != -UNW_ENOMEM) {<br>
> > +            if (ret != -UNW_EUNSPEC)<br>
> > +                ErrorFSigSafe("unw_get_proc_name failed: %s [%d]\n",<br>
> > +                        unw_strerror(ret), ret);<br>
> > +            procname[0] = '?';<br>
> > +            procname[1] = 0;<br>
> > +        }<br>
> > +<br>
> > +        if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&<br>
> > +                *dlinfo.dli_fname)<br>
> > +            filename = dlinfo.dli_fname;<br>
> > +        else<br>
> > +            filename = "?";<br>
> > +<br>
> > +        ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,<br>
> > +            ret == -UNW_ENOMEM ? "..." : "", (int)off,<br>
> > +            (void *)(pip.start_ip + off));<br>
> > +<br>
> > +        ret = unw_step(&cursor);<br>
> > +        if (ret < 0)<br>
> > +            ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret);<br>
> > +    }<br>
> > +    ErrorFSigSafe("\n");<br>
> > +}<br>
> > +#else /* HAVE_LIBUNWIND */<br>
> >  #ifdef HAVE_BACKTRACE<br>
> >  #ifndef _GNU_SOURCE<br>
> >  #define _GNU_SOURCE<br>
> > @@ -246,3 +320,4 @@ xorg_backtrace(void)<br>
> ><br>
> >  #endif<br>
> >  #endif<br>
> > +#endif<br>
> > --<br>
> > 1.8.1<br>
><br>
> thanks for the changes but after applying this patch locally I do wonder:<br>
> how did you test this? i'm getting undefined references to the various<br>
> libunwind calls (_Ux86_64_getcontext, _Ux86_64_strerror,etc) for Xvfb, Xdmx, Xnext<br>
> and all the tests). This needs some more polishing.</p>
<p>Try to do make clean before building.<br>
For some reason <a href="http://libos.la">libos.la</a> is not updated automatically.</p>
<p>Marcin<br>
</p>