Print backtrace in a signal-safe manner

Backtraces are often printed in signal context, such as when a segfault
occurs.

Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

os: print offset as unsigned int, not long unsigned int

pnprintf() takes unsigned int for %u

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Chase Douglas 2012-04-06 16:09:05 -07:00 committed by Keith Packard
parent ac20815d52
commit 0fa5217836

View File

@ -45,29 +45,37 @@ xorg_backtrace(void)
int size, i; int size, i;
Dl_info info; Dl_info info;
ErrorF("\n"); ErrorFSigSafe("\n");
ErrorF("Backtrace:\n"); ErrorFSigSafe("Backtrace:\n");
size = backtrace(array, 64); size = backtrace(array, 64);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
int rc = dladdr(array[i], &info); int rc = dladdr(array[i], &info);
if (rc == 0) { if (rc == 0) {
ErrorF("%d: ?? [%p]\n", i, array[i]); ErrorFSigSafe("%u: ?? [%p]\n", i, array[i]);
continue; continue;
} }
mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)"; mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)";
if (info.dli_saddr) if (info.dli_saddr)
ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod, ErrorFSigSafe(
"%u: %s (%s+0x%x) [%p]\n",
i,
mod,
info.dli_sname, info.dli_sname,
(long unsigned int) ((char *) array[i] - (unsigned int)((char *) array[i] -
(char *) info.dli_saddr), array[i]); (char *) info.dli_saddr),
array[i]);
else else
ErrorF("%d: %s (%p+0x%lx) [%p]\n", i, mod, ErrorFSigSafe(
"%u: %s (%p+0x%x) [%p]\n",
i,
mod,
info.dli_fbase, info.dli_fbase,
(long unsigned int) ((char *) array[i] - (unsigned int)((char *) array[i] -
(char *) info.dli_fbase), array[i]); (char *) info.dli_fbase),
array[i]);
} }
ErrorF("\n"); ErrorFSigSafe("\n");
} }
#else /* not glibc or glibc < 2.1 */ #else /* not glibc or glibc < 2.1 */
@ -105,7 +113,7 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
strcpy(signame, "unknown"); strcpy(signame, "unknown");
} }
ErrorF("** Signal %d (%s)\n", signo, signame); ErrorFSigSafe("** Signal %u (%s)\n", signo, signame);
} }
snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc); snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc);
@ -123,7 +131,8 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
symname = "<section start>"; symname = "<section start>";
offset = pc - (uintptr_t) dlinfo.dli_fbase; offset = pc - (uintptr_t) dlinfo.dli_fbase;
} }
ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname, symname, offset); ErrorFSigSafe("%s: %s:%s+0x%x\n", header, dlinfo.dli_fname, symname,
offset);
} }
else { else {
@ -131,7 +140,7 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
* probably poke elfloader here, but haven't written that code yet, * probably poke elfloader here, but haven't written that code yet,
* so we just print the pc. * so we just print the pc.
*/ */
ErrorF("%s\n", header); ErrorFSigSafe("%s\n", header);
} }
return 0; return 0;
@ -183,7 +192,7 @@ xorg_backtrace_pstack(void)
if (bytesread > 0) { if (bytesread > 0) {
btline[bytesread] = 0; btline[bytesread] = 0;
ErrorF("%s", btline); ErrorFSigSafe("%s", btline);
} }
else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN))) else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN)))
done = 1; done = 1;
@ -203,8 +212,8 @@ void
xorg_backtrace(void) xorg_backtrace(void)
{ {
ErrorF("\n"); ErrorFSigSafe("\n");
ErrorF("Backtrace:\n"); ErrorFSigSafe("Backtrace:\n");
#ifdef HAVE_PSTACK #ifdef HAVE_PSTACK
/* First try fork/exec of pstack - otherwise fall back to walkcontext /* First try fork/exec of pstack - otherwise fall back to walkcontext
@ -221,9 +230,9 @@ xorg_backtrace(void)
walkcontext(&u, xorg_backtrace_frame, &depth); walkcontext(&u, xorg_backtrace_frame, &depth);
else else
#endif #endif
ErrorF("Failed to get backtrace info: %s\n", strerror(errno)); ErrorFSigSafe("Failed to get backtrace info: %s\n", strerror(errno));
} }
ErrorF("\n"); ErrorFSigSafe("\n");
} }
#else #else