diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /xorg-server/os/backtrace.c | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'xorg-server/os/backtrace.c')
-rw-r--r-- | xorg-server/os/backtrace.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/xorg-server/os/backtrace.c b/xorg-server/os/backtrace.c new file mode 100644 index 000000000..b52dcded8 --- /dev/null +++ b/xorg-server/os/backtrace.c @@ -0,0 +1,201 @@ +/* + * Copyright 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software") + * to deal in the software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "os.h" +#include "misc.h" + +#ifdef HAVE_BACKTRACE +#include <execinfo.h> + +void xorg_backtrace(void) +{ + void *array[32]; /* deeper nesting than this means something's wrong */ + size_t size, i; + char **strings; + ErrorF("\nBacktrace:\n"); + size = backtrace(array, 32); + strings = backtrace_symbols(array, size); + for (i = 0; i < size; i++) + ErrorF("%d: %s\n", i, strings[i]); + free(strings); +} + +#else /* not glibc or glibc < 2.1 */ + +# if defined(sun) && defined(__SVR4) +# define HAVE_PSTACK +# endif + +# if defined(HAVE_WALKCONTEXT) /* Solaris 9 & later */ + +# include <ucontext.h> +# include <signal.h> +# include <dlfcn.h> +# include <sys/elf.h> + +#ifdef _LP64 +# define ElfSym Elf64_Sym +#else +# define ElfSym Elf32_Sym +#endif + +/* Called for each frame on the stack to print it's contents */ +static int xorg_backtrace_frame(uintptr_t pc, int signo, void *arg) +{ + Dl_info dlinfo; + ElfSym *dlsym; + char header[32]; + int depth = *((int *) arg); + + if (signo) { + char signame[SIG2STR_MAX]; + + if (sig2str(signo, signame) != 0) { + strcpy(signame, "unknown"); + } + + ErrorF("** Signal %d (%s)\n", signo, signame); + } + + snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc); + *((int *) arg) = depth + 1; + + /* Ask system dynamic loader for info on the address */ + if (dladdr1((void *) pc, &dlinfo, (void **) &dlsym, RTLD_DL_SYMENT)) { + unsigned long offset = pc - (uintptr_t) dlinfo.dli_saddr; + const char *symname; + + if (offset < dlsym->st_size) { /* inside a function */ + symname = dlinfo.dli_sname; + } else { /* found which file it was in, but not which function */ + symname = "<section start>"; + offset = pc - (uintptr_t)dlinfo.dli_fbase; + } + ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname, + symname, offset); + + } else { + /* Couldn't find symbol info from system dynamic loader, should + * probably poke elfloader here, but haven't written that code yet, + * so we just print the pc. + */ + ErrorF("%s\n", header); + } + + return 0; +} +# endif /* HAVE_WALKCONTEXT */ + +# ifdef HAVE_PSTACK +static int xorg_backtrace_pstack(void) { + pid_t kidpid; + int pipefd[2]; + + if (pipe(pipefd) != 0) { + return -1; + } + + kidpid = fork1(); + + if (kidpid == -1) { + /* ERROR */ + return -1; + } else if (kidpid == 0) { + /* CHILD */ + char parent[16]; + + seteuid(0); + close(STDIN_FILENO); + close(STDOUT_FILENO); + dup2(pipefd[1],STDOUT_FILENO); + closefrom(STDERR_FILENO); + + snprintf(parent, sizeof(parent), "%d", getppid()); + execle("/usr/bin/pstack", "pstack", parent, NULL); + exit(1); + } else { + /* PARENT */ + char btline[256]; + int kidstat; + int bytesread; + int done = 0; + + close(pipefd[1]); + + while (!done) { + bytesread = read(pipefd[0], btline, sizeof(btline) - 1); + + if (bytesread > 0) { + btline[bytesread] = 0; + ErrorF("%s", btline); + } + else if ((bytesread < 0) || + ((errno != EINTR) && (errno != EAGAIN))) + done = 1; + } + close(pipefd[0]); + waitpid(kidpid, &kidstat, 0); + if (kidstat != 0) + return -1; + } + return 0; +} +# endif /* HAVE_PSTACK */ + + +# if defined(HAVE_PSTACK) || defined(HAVE_WALKCONTEXT) + +void xorg_backtrace(void) { + + ErrorF("\nBacktrace:\n"); + +# ifdef HAVE_PSTACK +/* First try fork/exec of pstack - otherwise fall back to walkcontext + pstack is preferred since it can print names of non-exported functions */ + + if (xorg_backtrace_pstack() < 0) +# endif + { +# ifdef HAVE_WALKCONTEXT + ucontext_t u; + int depth = 1; + + if (getcontext(&u) == 0) + walkcontext(&u, xorg_backtrace_frame, &depth); + else +# endif + Error("Failed to get backtrace info"); + } + ErrorF("\n"); +} + +# else + +/* Default fallback if we can't find any way to get a backtrace */ +void xorg_backtrace(void) { return; } + +# endif +#endif |