void xorg_backtrace(void) { ErrorFSigSafe("\n"); ErrorFSigSafe("Backtrace:\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 ErrorFSigSafe("Failed to get backtrace info: %s\n", strerror(errno)); } ErrorFSigSafe("\n"); }
void OsVendorFatalError(const char *f, va_list args) { #ifdef VENDORSUPPORT ErrorFSigSafe("\nPlease refer to your Operating System Vendor support " "pages\nat %s for support on this crash.\n", VENDORSUPPORT); #else ErrorFSigSafe("\nPlease consult the " XVENDORNAME " support \n\t at " __VENDORDWEBSUPPORT__ "\n for help. \n"); #endif if (xf86LogFile && xf86LogFileWasOpened) ErrorFSigSafe("Please also check the log file at \"%s\" for additional " "information.\n", xf86LogFile); ErrorFSigSafe("\n"); }
/* 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"); } ErrorFSigSafe("** Signal %u (%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; } ErrorFSigSafe("%s: %s:%s+0x%x\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. */ ErrorFSigSafe("%s\n", header); } return 0; }
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; ErrorFSigSafe("%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; }
void LogClose(enum ExitCode error) { if (logFile) { ErrorFSigSafe("Server terminated %s (%d). Closing log file.\n", (error == EXIT_NO_ERROR) ? "successfully" : "with error", error); fclose(logFile); logFile = NULL; logFileFd = -1; } }
OsSigHandler(int signo) #endif { #ifdef RTLD_DI_SETSIGNAL const char *dlerr = dlerror(); if (dlerr) { LogMessageVerbSigSafe(X_ERROR, 1, "Dynamic loader error: %s\n", dlerr); } #endif /* RTLD_DI_SETSIGNAL */ if (OsSigWrapper != NULL) { if (OsSigWrapper(signo) == 0) { /* ddx handled signal and wants us to continue */ return; } } /* log, cleanup, and abort */ xorg_backtrace(); #ifdef SA_SIGINFO if (sip->si_code == SI_USER) { ErrorFSigSafe("Received signal %u sent by process %u, uid %u\n", signo, sip->si_pid, sip->si_uid); } else { switch (signo) { case SIGSEGV: case SIGBUS: case SIGILL: case SIGFPE: ErrorFSigSafe("%s at address %p\n", strsignal(signo), sip->si_addr); } } #endif FatalError("Caught signal %d (%s). Server aborting\n", signo, strsignal(signo)); }
void xorg_backtrace(void) { void *array[64]; const char *mod; int size, i; Dl_info info; ErrorFSigSafe("\n"); ErrorFSigSafe("Backtrace:\n"); size = backtrace(array, 64); for (i = 0; i < size; i++) { int rc = dladdr(array[i], &info); if (rc == 0) { ErrorFSigSafe("%u: ?? [%p]\n", i, array[i]); continue; } mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)"; if (info.dli_saddr) ErrorFSigSafe( "%u: %s (%s+0x%x) [%p]\n", i, mod, info.dli_sname, (unsigned int)((char *) array[i] - (char *) info.dli_saddr), array[i]); else ErrorFSigSafe( "%u: %s (%p+0x%x) [%p]\n", i, mod, info.dli_fbase, (unsigned int)((char *) array[i] - (char *) info.dli_fbase), array[i]); } ErrorFSigSafe("\n"); }
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"); }