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