c/8743: receiving result from __builtin_return_address() beyond stack top causes segfault

eddy@opera.no eddy@opera.no
Fri Nov 29 06:08:00 GMT 2002


>Number:         8743
>Category:       c
>Synopsis:       receiving result from __builtin_return_address() beyond stack top causes segfault
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Nov 28 05:16:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     eddy@opera.no
>Release:        gcc-3.0.4
>Organization:
>Environment:
Debian GNU/Linux 2.2.19pre17 #1 Tue Mar 13 22:37:59 EST 2001 i686 unknown
>Description:
The program shown below as `How-To-Repeat' segfaults when built with gcc-3.0.4 or 2.95.4; though (void)ing the function's return instead of storing (or attempting to print) it is OK.  This is despite the info page saying: <quote>

Getting the Return or Frame Address of a Function
=================================================
...
     On some machines it may be impossible to determine the return
     address of any function other than the current one; in such cases,
     or when the top of the stack has been reached, this function will
     return `0'.
...
</quote> which I read as meaning I should be getting the value 0 if I call with LEVEL greater than the actual depth of the stack.  The builtin works fine from deep in a stack all the way up to top-of-stack, but recieving its result from a call asking about frames above that causes a segfault.

Bug initially discovered in the course of trying to use ccmalloc; I wasn't even getting into main(), since libqt.so's loading called malloc, which asked for a backtrace, which segfaulted, before main() was invoked ! (This destroyed the work-around I initially thought of, namely having main() call a function which lets the backtracer record main()'s address as a sentinel at which to stop.)

Note that this bug makes it impossible to use this builtin for backtracing, since one has no way of detecting the depth from which one is calling it.  For use in generation of backtraces, at least the first invalid LEVEL needs to return a sentinel value, without segfaulting.
>How-To-Repeat:
cat >backtrace.c <<EOF
int main(int count, char *args[])
{
	void *tmp = __builtin_return_address(2);
	return 0;
}
EOF
gcc -o backtrace backtrace.c
backtrace
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list