No backtrace from SIGABRT signal on Tx2

I’m using ‘backtrace()’ and ‘backtrace_symbols’ functions in a signal handler to generate a backtrace for debugging (without gdb).

On Tx2, the backtrace() on SIGABRT signal shows only three frames: the signal handler and two from within libc, which is not useful.

Stack Trace:
Signal (6), Aborted
[Bt0] status(0), ./App: pfnExceptionHandler_linux(int, siginfo_t*, void*) + 0x17c [0x555eaef9fc]
[Bt1] status(-2), linux-vdso.so.1: __kernel_rt_sigreturn + 0 [0x7f7b09f6c0]
[Bt2] status(-2), /lib/aarch64-linux-gnu/libc.so.6: raise + 0xb0 [0x7f7ad514a8]

Backtrace on SIGSEGV does produce a good backtrace.

Stack Trace:
Signal (11), Segmentation fault
[Bt0] status(0), ./App: pfnExceptionHandler_linux(int, siginfo_t*, void*) + 0x17c [0x55785579ac]
[Bt1] status(-2), linux-vdso.so.1: __kernel_rt_sigreturn + 0 [0x7fa97046c0]
[Bt2] status(0), ./App: testfunc() + 0x10 [0x5578558038]
[Bt3] status(-2), ./App: main + 0x24 [0x557855806c]
[Bt4] status(-2), /lib/aarch64-linux-gnu/libc.so.6: __libc_start_main + 0xe0 [0x7fa93a46e0]
[Bt5] status(-2), ./App: + 0x70a4 [0x55785570a4]

How can I get a useful backbrace on SIGABRT on Tx2?

some codes

  1. signal handler
    void pfnExceptionHandler_linux(int signum, siginfo_t* info, void* ctx)
    {
    signal(signum, SIG_DFL);

    const size_t sFrameSize = 100;
    void* pStackBuffer[sFrameSize] = { 0 };
    int iSize = backtrace(pStackBuffer, sFrameSize);
    char** symbols = backtrace_symbols(pStackBuffer, iSize);
    if (!symbols)
    {
    return;
    }

  2. test function
    void testfunc()
    {
    int *a = NULL;
    //assert(a != NULL);
    *a = 1;
    }

int main(int argc, char **argv)
{
registerExceptionHandler();

printf("Hello world\n");

testfunc();

return 0;

}

Hello,

Moving this to the Jetson TX2 category for visibility.

I’m probably way off on this, but it might be in part an issue of compile options. Was this compiled with “-g” and without optimizing (or at least “-O0`”)? Also, and perhaps most important, is that it is calling a library in the stack frame. It is the library which needs debug symbols in order to see what is there (your stack frame is valid and correct for your application, but the library can’t show more without debug symbols).

Note that there is usually a debug version available for any library. For example, “libc6-dbg” would be required for for seeing the calls within libc6 (and you might need to recompile your program against the debug version). I don’t know where to get the debug version linux-vdso, but you’d also need the debug version of this to see details inside a call to that library.

Sort of related to this, if your program is multi-threaded, then you might also need to run it to dump for each thread with an identifier of the thread PID for all threads, and then find the right file (don’t know if this applies to your case, but be aware of it).

Thanks for your help

Thank you for your reply.

I use the g++ compiler with “-g” and “-rdynaimc”, but it does not work. I also try gcc compiler and compile options “-funwind-tables”, “-ffunction-sections”, “-O0”, etc, but these are useless.

The same codes and compiling with “-g” and “-rdynaimc” work fine on x86 Ubuntu desktop. I can get a useful backbrace on both SIGABRT and SIGSEGV signals.

The “-rdynamic” allows adding symbols even if not used (useful if the linked library is in a dynamic path and not part of the system’s linker path; see “ldconfig -p” to view what is in the linker path). However, if you were to link to a custom library location, and the debugger were to try to follow this, then the library itself would still need to have debug symbols if the debugger is to provide a stack trace of code within that library (the program which sees where or how to link is only the first step in allowing the debugger to see what code is being called; expanding to see function names and source code within the library is a separate step). The “-rdynamic” might confuse a debugger.

I have not used rdynamic in a long time, but I recall it sometimes changing debugging in unexpected ways. This can actually remove part of the stack frame details. Do you need “-rdynamic”? Any stack frame you get this way might be limited because of this.

Just to emphasize, you do need “-g” and “-O0”, but this has to apply to the library itself and not the original program if the debugger is to be able to see details of function calls within the library. Do you have the debug symbols in the related libraries, e.g., “linux-vdso.so.1” and “libc.so.6”?

Also, are there any fork calls in this? An interesting URL on the topic:
https://sourceware.org/gdb/onlinedocs/gdb/Forks.html.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.