[Beowulf] backtraces

Craig Tierney ctierney at hypermall.net
Mon Jun 11 13:58:59 PDT 2007


Mark Hahn wrote:
>>> It's highly dependant to implement but I should imagine most people who
>>> need backtraces use a debugger,
> 
> suppose your program is running on a hundred nodes for a week before you 
> hit the event you want the backtrace for...
> yes, debugger+coredump can be used, but for obvious reasons,
> we normally recommend users _not_ have them enabled.


Sorry to start a flame war....

Make sure that your code generates the exact same answer with 
debug/backtrace enabled and disabled, then you add user-level 
checkpointing so that you can restart where you want.  Then you
run up until the problem and restart with the last checkpoint.

Run for a week without checkpointing?  Just begging for trouble.

Craig



> 
>>> the libc backtrace() function or
>>> libbacktrace which can be use from either inside or outside the target
>>> process, these tend to be platform independent.
> 
> I started with the libc backtrace function, but wanted something better 
> than its backtrace_symbols() companion.
> 
>> libbacktrace is AFAICT also gcc specific. Or do you any pointers to 
>> some more platform-info on libbacktrace ?
> 
> I believe it's binutils/libc-specific, not compiler-specific.  at least 
> "pathcc -O3 -fno-inline-functions -g" gave me a meaningful backtrace on 
> an mpi tester.
> 
> anyway, appended is my current version of backtrace.c - I think it's 
> interesting and potentially useful, especially considering that it's not 
> really complex:
> 
> /* print a backtrace.
>    written by Mark Hahn, SHARCnet, 2007.
> 
> gcc -fPIC backtrace.c /usr/lib64/libbfd-2.15.92.0.2.so -shared -o 
> backtrace.so
> 
> using -lbfd chokes on a symbol addressing issue with (static) libbfd.a 
> on my system.  your libbfd version number may differ.
> 
> LD_PRELOAD=./backtrace.so ./tester
> signal(11)
> Obtained 9 stack frames.
> file: /home/hahn/private/tester.c, line: 10, func dosegv
> file: /home/hahn/private/tester.c, line: 14, func bar
> file: /home/hahn/private/tester.c, line: 17, func foo
> file: /home/hahn/private/tester.c, line: 29, func main
> 
> all symbols (globals and functions) are static to avoid contamination.
> 
> you need -g on the target program, and potentially something like
> -fno-inline-functions to dissuade the compiler from disappearing some 
> functions.
> */
> 
> #define _GNU_SOURCE
> #include <stdio.h>
> #include <stdlib.h>
> #include <dlfcn.h>
> #include <execinfo.h>
> #include <signal.h>
> #include <bfd.h>
> #include <unistd.h>
> 
> #define MAX_FRAMES (20)
> 
> /* globals retained across calls to resolve. */
> static bfd* abfd = 0;
> static asymbol **syms = 0;
> static asection *text = 0;
> 
> static void resolve(char *address) {
>     if (!abfd) {
>     char ename[1024];
>     int l = readlink("/proc/self/exe",ename,sizeof(ename));
>     if (l == -1) {
>         perror("failed to find executable\n");
>         return;
>     }
>     ename[l] = 0;
> 
>     bfd_init();
> 
>     abfd = bfd_openr(ename, 0);
>     if (!abfd) {
>         perror("bfd_openr failed: ");
>         return;
>     }
>     /* oddly, this is required for it to work... */
>     bfd_check_format(abfd,bfd_object);
> 
>     unsigned storage_needed = bfd_get_symtab_upper_bound(abfd);
>     syms = (asymbol **) malloc(storage_needed);
>     unsigned cSymbols = bfd_canonicalize_symtab(abfd, syms);
> 
>     text = bfd_get_section_by_name(abfd, ".text");
>     }
>     long offset = ((long)address) - text->vma;
>     if (offset > 0) {
>         const char *file;
>         const char *func;
>         unsigned line;
>         if (bfd_find_nearest_line(abfd, text, syms, offset, &file, 
> &func, &line) && file)
>             printf("file: %s, line: %u, func %s\n",file,line,func);
>     }
> }
> 
> static void print_trace() {
>     void *array[MAX_FRAMES];
>     size_t size;
>     size_t i;
>     void *approx_text_end = (void*) ((128+100) * 2<<20);
> 
>     size = backtrace (array, MAX_FRAMES);
>     printf ("Obtained %zd stack frames.\n", size);
>     for (i = 0; i < size; i++) {
>     if (array[i] < approx_text_end) {
>         resolve(array[i]);
>     }
>     }
> }
> 
> static void handler(int sig) {
>     printf("signal(%d)\n",sig);
>     print_trace();
>     _exit(1);
> }
> 
> static void __attribute__((constructor)) init() {
>     static struct sigaction sa;
>     sa.sa_handler = handler;
>     sigaction(SIGABRT, &sa, 0);
>     sigaction(SIGFPE, &sa, 0);
>     sigaction(SIGSEGV, &sa, 0);
> }
> _______________________________________________
> Beowulf mailing list, Beowulf at beowulf.org
> To change your subscription (digest mode or unsubscribe) visit 
> http://www.beowulf.org/mailman/listinfo/beowulf
> 




More information about the Beowulf mailing list