Sunday, July 22, 2007

use backtrace to get call stack information (GNU C library)

We can use GNU C lib backtrace functions to get call stack on Linux OS.
int backtrace (void **buffer, int size)
char ** backtrace_symbols (void *const *buffer, int size)
header file:
execinfo.h
in order to get the symbols, we need pass -rdynamic to gcc.
-rdynamic will
pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table.

Limitation: it only works when backtrace is provided in GNU C. It does not work on Mac.


Compile: gcc -o mytrace mytrace.c -rdynamic

Example Result:
Obtained 6 stack frames.
./mytrace(print_trace+0x14) [0x8048724]
./mytrace(dummy_function+0xb) [0x80487b7]
./mytrace(dummy_function_1+0xb) [0x80487a7]
./mytrace(main+0xb) [0x80487c7]
/lib/libc.so.6(__libc_start_main+0xa9) [0x4003b54d]
./mytrace(backtrace_symbols+0x35) [0x8048631]


Example:

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

/* Obtain a backtrace and print it to stdout. */
void
print_trace (void)
{
void *array[10];
size_t size;
char **strings;
size_t i;

size = backtrace (array, 10);
strings = backtrace_symbols (array, size);

printf ("Obtained %zd stack frames.\n", size);

for (i = 0; i < size; i++)
printf ("%s\n", strings[i]);

free (strings);
}

void
dummy_function_1 (void)
{
dummy_function();
}
/* A dummy function to make the backtrace more interesting. */
void
dummy_function (void)
{
print_trace ();
}

int
main (void)
{
dummy_function_1();
return 0;
}

No comments: