i'm using 'backtrce()' , 'backtrace_symbols_fd()' functions in signal handler generate backtrace debugging (gdb not available).
they work fine on x86 desktop (ubuntu), on target device (arm based) backtrace on abort signal (due double-free error) shows 3 frames: signal handler , 2 within libc, not useful debugging our code! backtrace on segv (e.g. using bad pointer) produce backtrace.
why can't useful backtrace on abrt signal on arm?
[question edited clarity]
here's simple test program demonstrates problem:
#include <execinfo.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> // signal hangler catch seg fault: void handler_segv(int sig) { // void*'s entries on stack void *array[10]; size_t size; size = backtrace(array, 10); fprintf(stderr, "error: signal %d; %d frames found:\n", sig, size); // print out frames stderr backtrace_symbols_fd(array, size, stderr_fileno); exit(1); } void crashme() { // deliberate error: abort (double free): char *test_ptr = malloc(1); free(test_ptr); free(test_ptr); // deliberate error #2: seg fault: //char * p = null; //*p = 0; } void foo() { fprintf(stdout, "---->about crash...\n"); crashme(); fprintf(stdout, "---->crashed (shouldn't here)...\n"); } // main entry point: int main(int argc, char *argv[]) { fprintf(stdout, "application start...\n"); // install signal handlers: fprintf(stdout, "-->adding handler sigsegv , sigabrt\n"); signal(sigsegv, handler_segv); signal(sigabrt, handler_segv); fprintf(stdout, "-->ok. causing error...\n"); foo(); fprintf(stdout, "-->test finished (shouldn't here!)\n"); return 0; } this compiled x86 follows:
gcc -o test test-backtrace-simple.c -g -rdynamic and arm:
arm-none-linux-gnueabi-gcc -o test-arm test-backtrace-simple.c -g -rdynamic -o0 -mapcs-frame -funwind-tables -fasynchronous-unwind-tables i've used various compiler options arm described in other posts related generating backtraces on arm.
when run on x86 desktop, generates expected output plenty of debug, ending in:
error: signal 6; 10 frames found: ./test(handler_segv+0x19)[0x80487dd] [0xb7745404] [0xb7745428] /lib/i386-linux-gnu/libc.so.6(gsignal+0x4f)[0xb75b0e0f] /lib/i386-linux-gnu/libc.so.6(abort+0x175)[0xb75b4455] /lib/i386-linux-gnu/libc.so.6(+0x6a43a)[0xb75ed43a] /lib/i386-linux-gnu/libc.so.6(+0x74f82)[0xb75f7f82] ./test(crashme+0x2b)[0x8048855] ./test(foo+0x33)[0x804888a] ./test(main+0xae)[0x8048962] (i.e. trace generated handler, function calls @ bottom).
however, when run on arm platform, get:
application start... -->adding handler sigsegv , sigabrt -->ok. causing error... ---->about crash... *** error in `/opt/bin/test-arm': double free or corruption (fasttop): 0x015b6008 *** error: signal 6; 3 frames found: /opt/bin/test-arm(handler_segv+0x24)[0x8868] /lib/libc.so.6(__default_sa_restorer_v2+0x0)[0xb6e6c150] /lib/libc.so.6(gsignal+0x34)[0xb6e6af48] the backtrace() finds 3 frames, , signal handler , in libc (not useful)!
i found mailing list post said:
if link debugging c library, -lc_g, you'll debugging info past abort().
this might relevant, -lc_g doesn't work on compiler (ld: cannot find -lg_c).
the backtrace works fine on arm if generate seg fault instead (e.g. change crashme() function use "char *p = null; *p = 0;" instead of double free.
any ideas or suggestions other ways trace?
[--edit--]
i tried malloc_check_ options suggested in comments, effect change whether abort generated. here output 3 runs on arm:
# malloc_check_=0 /opt/bin/test-arm application start... -->adding handler sigsegv , sigabrt -->ok. causing error... ---->about crash... ---->crashed (shouldn't here)... -->test finished (shouldn't here!) # malloc_check_=1 /opt/bin/test-arm application start... -->adding handler sigsegv , sigabrt -->ok. causing error... ---->about crash... *** error in `/opt/bin/test-arm': free(): invalid pointer: 0x015b2008 *** ---->crashed (shouldn't here)... -->test finished (shouldn't here!) # malloc_check_=2 /opt/bin/test-arm application start... -->adding handler sigsegv , sigabrt -->ok. causing error... ---->about crash... error: signal 6; 3 frames found: /opt/bin/test-arm(handler_segv+0x24)[0x8868] /lib/libc.so.6(__default_sa_restorer_v2+0x0)[0xb6e24150] /lib/libc.so.6(gsignal+0x34)[0xb6e22f48] # malloc_check_=0: no error message (double free ignored!)
malloc_check_=1: error message, program continues
malloc_check_=2: error message , abrt signal; useless backtrace generated (this default behaviour!)
my cross compiler reports: gcc version 4.6.1 (sourcery codebench lite 2011.09-70) target device has linux kernel version 3.8.8
i having same problem. tried built-in backtrace_symbols() method , found worked, stopped @ signal handler. tried backward.hpp , deathhandler similar results.
libubwind v1.2rc working me sigsegv, sigabrt using own signal handler (no special code inside this, requesting backtrace libunwind). give try.
Comments
Post a Comment