Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Backtrace

13 views
Skip to first unread message

Peter Nieheus

unread,
Dec 13, 2004, 5:45:36 PM12/13/04
to
Hi,

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

Andrew Taylor

unread,
Dec 13, 2004, 7:39:48 PM12/13/04
to
Peter Nieheus wrote:
>
> 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?

Link with -rdynamic to retain the symbol table.

--
Andrew

John Reiser

unread,
Dec 13, 2004, 7:47:57 PM12/13/04
to
> size = backtrace (array, 10);
> strings = backtrace_symbols (array, size);
>

> 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.

--

Peter Nieheus

unread,
Dec 14, 2004, 7:50:27 AM12/14/04
to
Andrew Taylor schrieb:


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

John Reiser

unread,
Dec 14, 2004, 10:24:08 AM12/14/04
to
>>> I want to see the function names, why do I not see them?

>> 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.

--

Otto Wyss

unread,
Dec 14, 2004, 2:13:06 PM12/14/04
to
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?

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

Måns Rullgård

unread,
Dec 14, 2004, 2:40:00 PM12/14/04
to
otto...@orpatec.ch (Otto Wyss) writes:

> 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

Peter Nieheus

unread,
Dec 14, 2004, 4:47:40 PM12/14/04
to
ok, with -rdynamic it worked.

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


Måns Rullgård

unread,
Dec 14, 2004, 4:55:58 PM12/14/04
to
Peter Nieheus <PeterN...@hemaho.mine.nu> writes:

> 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

Peter Nieheus

unread,
Dec 14, 2004, 5:03:30 PM12/14/04
to
Måns Rullgård schrieb:

no, the same output,...

Peter Nieheus

unread,
Dec 14, 2004, 5:03:52 PM12/14/04
to
Måns Rullgård schrieb:

no, the same output

Otto Wyss

unread,
Dec 16, 2004, 1:04:33 PM12/16/04
to
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.

Måns Rullgård

unread,
Dec 16, 2004, 1:40:51 PM12/16/04
to
otto...@orpatec.ch (Otto Wyss) writes:

> 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

Peter Nieheus

unread,
Dec 20, 2004, 5:10:50 PM12/20/04
to
Peter Nieheus schrieb:

> Hi,
>
> I use this example to test the Backtrace-function:
>
>
> test.c:
> //#########################################
> .....

Thanks to all, here is my full solution:

http://www.linuxjournal.com/node/6391

0 new messages