views:

83

answers:

5

Hi,

I am currently porting our code from an alpha (Tru64) to an i386 processor (Linux) in C. Everything has gone pretty smoothly up until I looked into porting our exception handling routine. Currently we have a parent process which spawns lots of sub processes, and when one of these sub-processes fatal's (unfielded) I have routines to catch the process.

I am currently struggling to find the best method of implementing a traceback routine which can list the function addresses in the error log, currently my routine just prints the the signal which caused the exception and the exception qualifier code.

Any help would be greatly received, ideally I would write error handling for all processors, however at this stage I only really care about i386, and x86_64.

Thanks

Mark

A: 

Unfortunately, there isn't a "best" method since the layout of the stack can vary depending on the CPU, the OS and the compiler used to compile your code. But this article may help.

Note that you must implement this in the child process; the parent process just gets a signal that something is wrong; you don't get a copy of the child stack.

Aaron Digulla
Sorry for the confusion but the error handling was misunderstood and it does indeed get caught in the child process. Also please note I am using the GNU compiler (gcc).
In that case, the article should answer all your questions. Note that you must compile with `-fno-omit-frame-pointer` (otherwise `%ESP` won't contain valid data).
Aaron Digulla
A: 

If a comment, you state you are using gcc. This http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Return-Address.html#Return-Address could be useful.

AProgrammer
+1  A: 

You might look at http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV. It covers the functionality you need. However you must link against libgdb and libdl, compile with -rdynamic (includes more symbols in the executable), and forgo the use of some optimizations.

edgar.holleis
+1  A: 

There are two GNU (non-POSIX) functions that can help you - backtrace() and backtrace_symbols() - first returns array of function addresses and second resolves addresses to names. Unfortunately names of static functions cannot be resolved.

To get it working you need to compile your binary with -rdynamic flag.

qrdl
+1  A: 

The glibc functions backtrace() and backtrace_symbols(), from execinfo.h, might be of use.

caf