Discussion:
Does __builtin_frame_address() work with C++ code?
Sam Varshavchik
2012-07-30 10:50:15 UTC
Permalink
I suspect that the answer is no. I don't seem to have much difficulty in
getting __builtin_frame_address() to segfault when using C++ code, in gcc
4.7, like with the following example (on x86-64).

I'm looking at all the work that glibc's backtrace() does, and it's a far
cry from what I see that __builtin_frame_address() generates.


#include <iostream>
#include <execinfo.h>

void *getframeaddr(int i)
{
void *p=0;

switch (i) {
case 1: p=__builtin_frame_address(1); break;
case 2: p=__builtin_frame_address(2); break;
case 3: p=__builtin_frame_address(3); break;
case 4: p=__builtin_frame_address(4); break;
case 5: p=__builtin_frame_address(5); break;
case 6: p=__builtin_frame_address(6); break;
case 7: p=__builtin_frame_address(7); break;
case 8: p=__builtin_frame_address(8); break;
case 9: p=__builtin_frame_address(9); break;
case 10: p=__builtin_frame_address(10); break;
case 11: p=__builtin_frame_address(11); break;
case 12: p=__builtin_frame_address(12); break;
case 13: p=__builtin_frame_address(13); break;
case 14: p=__builtin_frame_address(14); break;
case 15: p=__builtin_frame_address(15); break;
case 16: p=__builtin_frame_address(16); break;
case 17: p=__builtin_frame_address(17); break;
case 18: p=__builtin_frame_address(18); break;
case 19: p=__builtin_frame_address(19); break;
case 20: p=__builtin_frame_address(20); break;
case 21: p=__builtin_frame_address(21); break;
case 22: p=__builtin_frame_address(22); break;
case 23: p=__builtin_frame_address(23); break;
case 24: p=__builtin_frame_address(24); break;
case 25: p=__builtin_frame_address(25); break;
case 26: p=__builtin_frame_address(26); break;
case 27: p=__builtin_frame_address(27); break;
case 28: p=__builtin_frame_address(28); break;
case 29: p=__builtin_frame_address(29); break;
case 30: p=__builtin_frame_address(30); break;
case 31: p=__builtin_frame_address(31); break;
case 32: p=__builtin_frame_address(32); break;
}
return p;
}

class mystreambuf : public std::streambuf {

public:

int underflow()
{
int i;

for (i=1; i<32; i++)
{
void *p=getframeaddr(i);

if (!p)
break;

std::cout << p << std::endl;
}
return -1;
}
};

int main()
{
mystreambuf s;
std::string ss;

std::istream i(&s);

std::getline(i, ss);
return 0;
}
Ian Lance Taylor
2012-07-31 00:59:44 UTC
Permalink
Post by Sam Varshavchik
I suspect that the answer is no. I don't seem to have much difficulty in
getting __builtin_frame_address() to segfault when using C++ code, in gcc
4.7, like with the following example (on x86-64).
__builtin_frame_address works just as well for C++ as it does for C.
But in both cases whether it works with non-zero arguments depends on
the target and the compilation options. It should normally work if
you compile with -fno-omit-frame-pointer.
Post by Sam Varshavchik
I'm looking at all the work that glibc's backtrace() does, and it's a far
cry from what I see that __builtin_frame_address() generates.
Yes, the backtrace function is far more reliable.
__builtin_frame_address is intended to be a quick and dirty function
for debugging purposes.

Ian

Loading...