os: use libunwind to generate backtraces
Libunwind generates backtraces much more reliably than glibc's "backtrace". Before: 0: /opt/xserver/bin/X (0x400000+0x18ce36) [0x58ce36] 1: /opt/xserver/bin/X (xorg_backtrace+0x9) [0x58d119] 2: /opt/xserver/bin/X (0x400000+0x190d69) [0x590d69] 3: /lib64/libpthread.so.0 (0x7fb904268000+0x10a90) [0x7fb904278a90] 4: /lib64/libc.so.6 (ioctl+0x7) [0x7fb902fbf987] 5: /usr/lib64/libdrm.so.2 (drmIoctl+0x28) [0x7fb90405ffa8] 6: /usr/lib64/libdrm.so.2 (drmCommandWrite+0x1b) [0x7fb90406235b] 7: /usr/lib64/libdrm_nouveau.so.2 (nouveau_bo_wait+0x89) [0x7fb902009719] 8: /opt/xserver/lib/xorg/modules/drivers/nouveau_drv.so (0x7fb90220e000+0x76f3) [0x7fb9022156f3] 9: /opt/xserver/lib/xorg/modules/libexa.so (0x7fb9019c7000+0xbae0) [0x7fb9019d2ae0] 10: /opt/xserver/bin/X (0x400000+0x17d2b3) [0x57d2b3] 11: /opt/xserver/bin/X (0x400000+0xc9930) [0x4c9930] 12: /opt/xserver/bin/X (0x400000+0x3a81a) [0x43a81a] 13: /opt/xserver/bin/X (0x400000+0x3d6a1) [0x43d6a1] 14: /opt/xserver/bin/X (0x400000+0x2c2ca) [0x42c2ca] 15: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x7fb902f019b5] 16: /opt/xserver/bin/X (0x400000+0x2c60d) [0x42c60d] 17: ?? [0x0] After: 0: /opt/xserver/bin/X (OsSigHandler+0x39) [0x590d69] 1: /lib64/libpthread.so.0 (__restore_rt+0x0) [0x7fb904278a8f] 2: /lib64/libc.so.6 (ioctl+0x7) [0x7fb902fbf987] 3: /usr/lib64/libdrm.so.2 (drmIoctl+0x28) [0x7fb90405ffa8] 4: /usr/lib64/libdrm.so.2 (drmCommandWrite+0x1b) [0x7fb90406235b] 5: /usr/lib64/libdrm_nouveau.so.2 (nouveau_bo_wait+0x89) [0x7fb902009719] 6: /opt/xserver/lib/xorg/modules/drivers/nouveau_drv.so (nouveau_exa_download_from_screen+0x1a3) [0x7fb9022156f3] 7: /opt/xserver/lib/xorg/modules/libexa.so (exaGetImage+0x1f0) [0x7fb9019d2ae0] 8: /opt/xserver/bin/X (miSpriteGetImage+0x173) [0x57d2b3] 9: /opt/xserver/bin/X (compGetImage+0xb0) [0x4c9930] 10: /opt/xserver/bin/X (ProcGetImage+0x55a) [0x43a81a] 11: /opt/xserver/bin/X (Dispatch+0x341) [0x43d6a1] 12: /opt/xserver/bin/X (main+0x3ba) [0x42c2ca] 13: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x7fb902f019b5] 14: /opt/xserver/bin/X (_start+0x29) [0x42c60d] 15: ? (?+0x29) [0x29] Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Tested-by: Knut Petersen <knut.petersen@t-online.de>
This commit is contained in:
parent
e27b2e6163
commit
e21e183059
|
@ -308,6 +308,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.
|
||||
|
@ -1336,7 +1343,7 @@ AC_DEFINE(BIGREQS, 1, [Support BigRequests extension])
|
|||
|
||||
if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then
|
||||
DIX_LIB='$(top_builddir)/dix/dix.O'
|
||||
OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS)'
|
||||
OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS) $(LIBUNWIND_LIBS)'
|
||||
else
|
||||
DIX_LIB='$(top_builddir)/dix/libdix.la'
|
||||
OS_LIB='$(top_builddir)/os/libos.la'
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -30,6 +30,80 @@
|
|||
#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 failed: %s [%d]\n", unw_strerror(ret),
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = unw_init_local(&cursor, &context);
|
||||
if (ret) {
|
||||
ErrorFSigSafe("unw_init_local failed: %s [%d]\n", unw_strerror(ret),
|
||||
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 failed: %s [%d]\n",
|
||||
unw_strerror(ret), 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 failed: %s [%d]\n",
|
||||
unw_strerror(ret), 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 failed: %s [%d]\n", unw_strerror(ret), ret);
|
||||
}
|
||||
ErrorFSigSafe("\n");
|
||||
}
|
||||
#else /* HAVE_LIBUNWIND */
|
||||
#ifdef HAVE_BACKTRACE
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
@ -246,3 +320,4 @@ xorg_backtrace(void)
|
|||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue