[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libunwind-devel] Backtrace from signal handler on arm from threads
From: |
Henrik Grindal Bakken |
Subject: |
[Libunwind-devel] Backtrace from signal handler on arm from threads |
Date: |
Tue, 01 Feb 2011 15:07:21 +0100 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux) |
Hello. I'm using (trying to use) libunwind to obtain backtraces for
my product. The application is running on arm, and is multi-threaded
(pthreads).
What I see is that the obtain_backtrace() call SIGSEGVs right at the
beginning when the handler was called from a thread. If it's called
from the main thread, it doesn't seem to matter that other threads
exist.
I've tried printf()s immediately in obtain_backtrace(), and if they
print out the context pointer, they seem to die. The threads are
created joinable with custom stacks, but changing that doesn't seem to
affect libunwind.
I compile my product with -g -fno-omit-frame-pointer -mapcs-frame, and
I've been trying both with 0.99 and latest-and-greatest from git.
Does anyone have any ideas?
Here's my relevant code:
static size_t obtain_backtrace(void ** dest, size_t destsize, void * context)
{
unw_cursor_t cursor;
unw_context_t uc;
unw_context_t * ctx;
size_t i = 0;
int ret;
if (context) {
ctx = context;
} else {
if (unw_getcontext(&uc) < 0)
return 0;
ctx = &uc;
}
if (unw_init_local(&cursor, ctx) < 0)
return 0;
do {
unw_word_t ip;
unw_word_t sp;
unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp);
dest[i++] = (void*) ip;
} while ((ret = unw_step(&cursor)) > 0 && i < destsize);
return i;
}
static void show_backtrace(void * context)
{
void * addr[32];
size_t i = obtain_backtrace(addr, 32, context);
fputs("==== STACK TRACE ====\n", stderr);
backtrace_symbols_fd(addr, i, 2);
fputs("==== STACK TRACE DONE ====\n", stderr);
}
static void handler(int sig, siginfo_t * psi , void * ctxarg)
{
ucontext_t * ucontext = (ucontext_t *)ctxarg;
show_backtrace(ucontext);
signal(sig, SIG_DFL);
kill(getpid(), sig);
}
static void register_handler(void)
{
struct sigaction sa;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
// sa.sa_flags = SA_RESTART | SA_SIGINFO;
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
}
int main()
{
register_handler();
/* Create some threads using pthread_create(), and
* segfault/abort in one of them. */
}
--
Henrik Grindal Bakken <address@hidden>
PGP ID: 8D436E52
Fingerprint: 131D 9590 F0CF 47EF 7963 02AF 9236 D25A 8D43 6E52