I use this example to test the Backtrace-function:
test.c:
//#########################################
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
/* Obtain a backtrace and print it to stdout. */
void
print_trace (void)
{
void *array[10];
size_t size;
char **strings;
size_t i;
size = backtrace (array, 10);
strings = backtrace_symbols (array, size);
printf ("Obtained %zd stack frames.\n", size);
for (i = 0; i < size; i++)
printf ("%s\n", strings[i]);
free (strings);
}
/* A dummy function to make the backtrace more interesting. */
void
dummy_function (void)
{
print_trace ();
}
int main (void)
{
dummy_function ();
return 0;
}
//#########################################
I get this Output after compiling ("gcc -g test.c" or "gcc test.c"):
Obtained 5 stack frames.
./a.out [0x804846d]
./a.out [0x80484e6]
./a.out [0x8048509]
/lib/tls/libc.so.6(__libc_start_main+0xe0) [0x40040500]
./a.out [0x80483c1]
I want to see the function names, why do I not see them?
thanks in advance
Link with -rdynamic to retain the symbol table.
--
Andrew
> I get this Output after compiling ("gcc -g test.c" or "gcc test.c"):
>
> Obtained 5 stack frames.
> ./a.out [0x804846d]
> ./a.out [0x80484e6]
> ./a.out [0x8048509]
> /lib/tls/libc.so.6(__libc_start_main+0xe0) [0x40040500]
> ./a.out [0x80483c1]
>
>
> I want to see the function names, why do I not see them?
Because the function names are not in the in-memory runtime symbol table;
they are only in the debug and [static] linking in-file symbol tables.
Try linking with "-rdynamic", or use
-----
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char str[100+4096];
char path[4096];
path[readlink("/proc/self/exe", path, -1+ sizeof(path))] = '\0';
sprintf(str, "echo 'bt\ndetach\nquit\n' | gdb -batch -x /dev/stdin %s %d\n",
path, (int)getpid() );
system(str);
-----
instead of the backtrace* functions. See also my post
"backtraces at runtime in Linux" comp.os.linux.development.apps 2004-07-26
http://groups-beta.google.com/group/comp.os.linux.development.apps/messages/fb55a6c9a364d9bf,e61d9810dbad9faf,83623b753966476a,c38fcc872f978447,2d78674dc148ed1f,70530e4d642657da,cb2ff3cc44c77afa,409ffc87a76868d8?thread_id=a9383b86ae1faa2b&mode=thread&noheader=1&q=insubject:backtraces+insubject:at+insubject:runtime+insubject:in+insubject:Linux#doc_c38fcc872f978447
(including its thread) for a discussion.
--
thanks, it worked great.
If I put it into a SingalHandler for the SIGSEGV-Signal, it worked
too(if I produce a segmentation fault). But the last function is not
displayed, the function in which this SEGFAULT is produced.
How can I show this function?
thanks
>> Link with -rdynamic to retain the symbol table.
> thanks, it worked great.
>
> If I put it into a SingalHandler for the SIGSEGV-Signal, it worked
> too(if I produce a segmentation fault). But the last function is not
> displayed, the function in which this SEGFAULT is produced.
The code for backtrace*() is too simple to detect the stack structure
for invoking signal handlers. If you really want to see everything,
including line numbers and the names of sourcefiles (if compiled -g),
then use the on-demand invocation of gdb given in another reply.
--
> Because the function names are not in the in-memory runtime symbol table;
> they are only in the debug and [static] linking in-file symbol tables.
> Try linking with "-rdynamic", or use
Where do I find more about -rdynamic?
I've written a crashprint function for wxWidgets application but it
shouldn't be difficult to apply them elsewhere, see
"http://cvs.sf.net/viewcvs.py/wxcode/wxCode/components/crashprint/src/cr
ashprint.cpp?view=markup" and nearby. Of course any suggestion is also
welcomed.
O. Wyss
--
Development of frame buffer drivers: http://linux-fbdev.sf.net
Sample code snippets for wxWidgets: http://wxcode.sf.net
How to build well-designed applications: http://wxguide.sf.net
Desktop with a consistent look and feel: http://wyodesktop.sf.net
> John Reiser <jre...@BitWagon.com> wrote:
>
>> Because the function names are not in the in-memory runtime symbol table;
>> they are only in the debug and [static] linking in-file symbol tables.
>> Try linking with "-rdynamic", or use
>
> Where do I find more about -rdynamic?
man ld
--
Måns Rullgård
m...@inprovide.com
Now I have this code, it shows me the backtrace if it makes a SIGSEGV:
///////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
char * copy_str(char *dst, const char *src)
{
strcpy(dst, src);
//memset(dst,0,4);
return dst + strlen(src);
}
static void report_segfault(int signo, siginfo_t * sinf, void * arg)
{
void * btrace[50];
size_t size;
int fd = fileno(stderr);
size = backtrace(btrace, 50);
backtrace_symbols_fd(btrace, size, fd);
}
int setup_signal_handler(void)
{
struct sigaction act;
act.sa_flags = SA_ONESHOT | SA_SIGINFO;
act.sa_sigaction = report_segfault;
sigfillset(&act.sa_mask);
if(sigaction(SIGSEGV, &act, NULL)) return -1;
act.sa_handler = SIG_IGN;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESETHAND|SA_RESTART;
if(sigaction(SIGPIPE, &act, NULL)) return -1;
return 0;
}
int main(void)
{
char *src = "abc";
setup_signal_handler();
copy_str(NULL, src);
return 0;
}
///////////////////////////////////////////////////////////////////////////////////
Output:
./a.out[0x804889e]
[0xffffe440]
./a.out(copy_str+0x18)[0x804885c]
./a.out(main+0x3b)[0x80489be]
/lib/tls/libc.so.6(__libc_start_main+0xe0)[0x40040500]
./a.out[0x80487b1]
But if I changed the strcpy in the copy_str-function to memset (see
above) the output does not show that the SIGSEGV was in copy_str():
./a.out[0x80488a7]
[0xffffe440]
./a.out(main+0x3b)[0x80489c7]
/lib/tls/libc.so.6(__libc_start_main+0xe0)[0x40040500]
./a.out[0x80487b1]
why?
thanks in advance
> ok, with -rdynamic it worked.
>
> Now I have this code, it shows me the backtrace if it makes a SIGSEGV:
[...]
> Output:
> ./a.out[0x804889e]
> [0xffffe440]
> ./a.out(copy_str+0x18)[0x804885c]
> ./a.out(main+0x3b)[0x80489be]
> /lib/tls/libc.so.6(__libc_start_main+0xe0)[0x40040500]
> ./a.out[0x80487b1]
>
> But if I changed the strcpy in the copy_str-function to memset (see
> above) the output does not show that the SIGSEGV was in copy_str():
> ./a.out[0x80488a7]
> [0xffffe440]
> ./a.out(main+0x3b)[0x80489c7]
> /lib/tls/libc.so.6(__libc_start_main+0xe0)[0x40040500]
> ./a.out[0x80487b1]
>
> why?
The compiler probably inlined the memcpy(). Try disabling
optimizations with -O0.
--
Måns Rullgård
m...@inprovide.com
no, the same output,...
no, the same output
> otto...@orpatec.ch (Otto Wyss) writes:
>
> > Where do I find more about -rdynamic?
>
> man ld
My ld (version 2.15) doesn't have a -rdynamic, at least not documented
in the man pages.
> Måns Rullgård <m...@inprovide.com> wrote:
>
>> otto...@orpatec.ch (Otto Wyss) writes:
>>
>> > Where do I find more about -rdynamic?
>>
>> man ld
>
> My ld (version 2.15) doesn't have a -rdynamic, at least not documented
> in the man pages.
Sorry, my mistake. -rdynamic is a gcc flag, which causes gcc to add
--export-dynamic to the linker flags.
--
Måns Rullgård
m...@inprovide.com
Thanks to all, here is my full solution: