Hi,

in binaries compiled with gcc 3.4.6 on an x86_64 machine, I get the following 
behaviour. I wrote a little testcase:

int main(int argc, char **argv)
{
  unsigned long addr;
  if ( (addr = (unsigned long)(__builtin_frame_address(0))) )
  {
    printf ("0x%08lx\n", addr);
    if ( (addr = (unsigned long)(__builtin_frame_address(1))) )
    {
      printf ("0x%08lx\n", addr);
      if ( (addr = (unsigned long)(__builtin_frame_address(2))) )
      {
        printf ("0x%08lx\n", addr);
        
        // ... some more scopes ...
      }
    }
  }
  return 0;
}

This code is a bit ugly, I made it that way because of the part in gcc's 
manpages:

"CC also has two builtins that can assist you, but which may or may not be 
implemented fully on your architecture, and those are __builtin_frame_address 
and __builtin_return_address. Both of which want an immediate integer level 
(by immediate, I mean it can't be a variable)."

- but it doesn't change the outcome of the test, anyway.

I ran the test on three machines with the following results:

1)

[EMAIL PROTECTED] ~]$ uname -m
i686
[EMAIL PROTECTED] ~]$ gcc -v
Lese Spezifikationen von /usr/lib/gcc/i386-redhat-linux/3.4.6/specs
Konfiguriert 
mit: ../configure --prefix=/usr --mandir=/usr/share/man 
--infodir=/usr/share/info --enable-shared --enable-threads=posix 
--disable-checking --with-system-zlib --enable-__cxa_atexit 
--disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread-Modell: posix
gcc-Version 3.4.6 20060404 (Red Hat 3.4.6-10)
[EMAIL PROTECTED] ~]$ gcc -o test test.c && ./test
0xbfefc048
0xbfefc0a8
[EMAIL PROTECTED] ~]$

2)

[EMAIL PROTECTED] ~]$ uname -m
x86_64
[EMAIL PROTECTED] ~]$ gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured 
with: ../configure --prefix=/usr --mandir=/usr/share/man 
--infodir=/usr/share/info --enable-shared --enable-threads=posix 
--enable-checking=release --with-system-zlib --enable-__cxa_atexit 
--disable-libunwind-exceptions --enable-libgcj-multifile 
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk 
--disable-dssi --enable-plugin 
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic 
--host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20070626 (Red Hat 4.1.2-14)
[EMAIL PROTECTED] ~]$ gcc -o test test.c && ./test
0x7fffc400c8c0
[EMAIL PROTECTED] ~]$

3)

[EMAIL PROTECTED] ~]$ uname -m
x86_64
[EMAIL PROTECTED] ~]$ gcc -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured 
with: ../configure --prefix=/usr --mandir=/usr/share/man 
--infodir=/usr/share/info --enable-shared --enable-threads=posix 
--disable-checking --with-system-zlib --enable-__cxa_atexit 
--disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-10)
[EMAIL PROTECTED] ~]$ gcc -o test test.c && ./test
0x7fbffff8c0
0x35952357a8
0x7fbffff9a8
0x7fbffffb7b
0x454d414e54534f48
Segmentation fault
[EMAIL PROTECTED] ~]$


So, on the 32bit machine and on the 64bit machine running gcc 4.x, the end of 
the stack is found (__builtin_frame_address(n) returned 0x0). The output is a 
bit different, apparently on the 32bit machine, the stackframe of the caller 
of main() is also found, but that is not important for the error.

On the 64bit machine using gcc 3.4.6 however, at some point, garbage (?) is 
returned.

My questions now are, is this known behaviour / a known issue? I didn't find a 
fitting patch. Or, can the fix for it be backported from gcc 4.x to 3.4.x? I 
cannot switch to gcc 4.x for some other reasons. If all this doesn't result 
in a solution, is there maybe another way for me to determine which 
stackframe is the topmost one? (Should I just compare the function name 
with "main"? That'd be a bit dirty, wouldn't it?)


Thanks,
Tim München

Reply via email to