Archives


- Beowulf
- Beowulf Announce
- Scyld-users
- Beowulf on Debian

[Beowulf] backtraces

Many of your questions may have already been answered in earlier discussions or in the FAQ. The search results page will indicate current discussions as well as past list serves, articles, and papers.

Search

Mark Hahn hahn at mcmaster.ca
Mon Jun 11 12:43:12 PDT 2007


>> 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.

>> 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);
}



More information about the Beowulf mailing list