<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>