libunwind-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]