linux: hand-roll a backtrace printer instead of using backtrace_symbols
Why? Because backtrace_symbols calls malloc, which you can't do from a signal handler. Face? Palm.
This commit is contained in:
parent
75b9383d8a
commit
eb031d4013
|
@ -29,19 +29,28 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <dlfcn.h>
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
|
|
||||||
void xorg_backtrace(void)
|
void xorg_backtrace(void)
|
||||||
{
|
{
|
||||||
void *array[32]; /* deeper nesting than this means something's wrong */
|
void *array[64];
|
||||||
|
char *mod;
|
||||||
int size, i;
|
int size, i;
|
||||||
char **strings;
|
Dl_info info;
|
||||||
ErrorF("\nBacktrace:\n");
|
ErrorF("\nBacktrace:\n");
|
||||||
size = backtrace(array, 32);
|
size = backtrace(array, 64);
|
||||||
strings = backtrace_symbols(array, size);
|
for (i = 0; i < size; i++) {
|
||||||
for (i = 0; i < size; i++)
|
dladdr(array[i], &info);
|
||||||
ErrorF("%d: %s\n", i, strings[i]);
|
mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)";
|
||||||
free(strings);
|
if (info.dli_saddr)
|
||||||
|
ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod,
|
||||||
|
info.dli_sname, array[i] - info.dli_saddr, array[i]);
|
||||||
|
else
|
||||||
|
ErrorF("%d: %s (%p+0x%lx) [%p]\n", i, mod,
|
||||||
|
info.dli_fbase, array[i] - info.dli_fbase, array[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* not glibc or glibc < 2.1 */
|
#else /* not glibc or glibc < 2.1 */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user