Showing posts with label GCC. Show all posts
Showing posts with label GCC. Show all posts

Saturday, February 25, 2012

How to get function's name from function's pointer in C? (GCC extensions)

In my previous post I described how to get function's name from function's pointer in C under Windows for debug purposes.

In GCC you may use backtrace_symbolos declared in <execinfo.h>. An example looks like:

#include <execinfo.h>

void *pfunc = ...; /* pointer to some function */

void *buffer[1] = {pfunc};
char **strings = backtrace_symbols(buffer, 1);
if (strings == NULL) {
  perror("backtrace_symbols");
} else {
  printf("%s\n", strings[0]);
  free(strings);
}

You have to link with -rdynamic flag. The output looks like:

./a.out(myfunc+0) [0x400987]

If function is static name is omitted.

I recommend to use the things like this for debugging only.

How to print stack trace in C / C++ (GCC)

While discovering and debugging a large project it may be quite useful to print a stack trace. In Java I could use something like
new Exception().printStackTrace()
for that purpose. (Yes, I know, it looks stupid and I prefer not to commit a code like that to CVS, but this dirty hack can still be quite useful while debugging).

Is their anyway to achieve the same goal in C / C++?

Of course there is no portable solution. But several platforms provide their extensions. I recently discovered that GCC provides functions backtrace() and backtrace_symbols() declared in <execinfo.h>. An example is available here: http://linux.die.net/man/3/backtrace_symbols. We need to link with -rdynamic option. The output contains the name of executable file, the name of function (if available) and looks like:

./a.out(myfunc3+0x1c) [0x400904]
./a.out [0x400985]
./a.out(myfunc+0x23) [0x4009aa]
./a.out(main+0x78) [0x400a24]
/lib64/libc.so.6(__libc_start_main+0xf4) [0x377281d974]
./a.out [0x400839]

Or, in case of C++, the output can be:

a.out(_Z7myfunc3v+0x1c) [0x4009b4]
a.out(__gxx_personality_v0+0x18d) [0x400a35]
a.out(_Z6myfunci+0x23) [0x400a5b]
a.out(_Z6myfunci+0x1c) [0x400a54]
a.out(main+0x76) [0x400ad4]
/lib64/libc.so.6(__libc_start_main+0xf4) [0x377281d974]
a.out(__gxx_personality_v0+0x41) [0x4008e9]

Note that static function name is omitted in case of C or replaced with some dummy name in case of C++.

I still miss the information like source file names and line numbers. But at least this could give an idea of what to debug next.

However, I still wouldn't commit a code like that to production.