backtrace() missing some frames on 32bit x86_64-linux?

FX Coudert fxcoudert@gmail.com
Fri Aug 10 23:07:00 GMT 2007


Hi glibc hackers,

The GNU Fortran runtime library (part of GCC) uses backtrace() on  
glibc systems to provide backtraces of different kinds of errors.  
When used from a signal handler, I've experienced a case where the  
backtrace is missing a frame when compiled and linked as 32bit, but  
is OK as 64bit. The following short C testcase reproduces this (glibc  
2.3.6 on linux 2.6.18, amd64):

> #include <stddef.h>
> #include <signal.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <execinfo.h>
>
> void
> handler (int signum)
> {
>   void *trace[50];
>   int depth = backtrace (trace, 50), i;
>   char **str;
>
>   str = backtrace_symbols (trace, depth);
>   for (i = 0; i < depth; i++)
>     printf ("%s\n", str[i]);
>
>   _exit (1);
> }
>
> int main (void)
> {
>   int * foo = NULL;
>
>   signal (SIGSEGV, handler);
>
>
>   *foo = 42;
>   return 0;
> }

When compiled and run with -m64, it gives:

> $ gcc a.c -m64 -g && ./a.out
> ./a.out [0x40060e]
> /lib/libc.so.6 [0x2aeb0d8c2110]
> ./a.out [0x40067b]
> /lib/libc.so.6(__libc_start_main+0xda) [0x2aeb0d8af4ca]
> ./a.out [0x40052a]

where 0x40060e is inside the handler and 0x40067b is in the main  
function. On the other hand, when compiled with -m32, it gives:

> $ gcc a.c -m32 -g && ./a.out
> ./a.out [0x80484a3]
> [0xffffe500]
> /lib32/libc.so.6(__libc_start_main+0xd3) [0xf7e0cea3]
> ./a.out [0x80483d1]

which makes no mention of the main function any more, but references  
the strange 0xffffe500 address instead. Is that a known shortcoming  
of backtrace(), am I using it wrongly and how could I do it otherwise?

Thanks for your help,
FX

PS: I'm not subscribed to the list, so please CC me your answers



More information about the Libc-alpha mailing list