symbol table for backtrace

C

cgable2003

I copied this code fragment from http://www.gnu.org/software/libc/manual/html_node/Backtraces.html

#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);

free (strings);
}

/* A dummy function to make the backtrace more interesting. */
void
dummy_function (void)
{
print_trace ();
}

int
main (void)
{
dummy_function ();
return 0;
}


/*************************************************************/
This program produces this output:
Obtained 5 stack frames.
.../bin/backtrace2(__gxx_personality_v0+0x149) [0x8048629]
.../bin/backtrace2(__gxx_personality_v0+0x1d9) [0x80486b9]
.../bin/backtrace2(__gxx_personality_v0+0x201) [0x80486e1]
/lib/libc.so.6(__libc_start_main+0xdd) [0xb7ce00dd]
.../bin/backtrace2(__gxx_personality_v0+0x81) [0x8048561]

/**************************************************************/
nm produces this symbol table

080499f4 V DW.ref.__gxx_personality_v0
080498c0 A _DYNAMIC
080499c4 D _GLOBAL_OFFSET_TABLE_
080487f0 R _IO_stdin_used
w _Jv_RegisterClasses
08048604 T _Z11print_tracev
080486a2 T _Z14dummy_functionv
080498b0 d __CTOR_END__
080498ac d __CTOR_LIST__
080498b8 d __DTOR_END__
080498b4 d __DTOR_LIST__
080488a8 r __FRAME_END__
080498bc d __JCR_END__
080498bc d __JCR_LIST__
080499f8 A __bss_start
080499e8 D __data_start
080487a0 t __do_global_ctors_aux
08048590 t __do_global_dtors_aux
080499ec D __dso_handle
080498ac A __fini_array_end
080498ac A __fini_array_start
w __gmon_start__
U __gxx_personality_v0@@CXXABI_1.2
080486eb T __i686.get_pc_thunk.bx
080498ac A __init_array_end
080498ac A __init_array_start
08048750 T __libc_csu_fini
080486f0 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
080499f8 A _edata
080499fc A _end
080487d0 T _fini
080487ec R _fp_hw
080484b8 T _init
08048540 T _start
U backtrace@@GLIBC_2.1
U backtrace_symbols@@GLIBC_2.1
08048564 t call_gmon_start
080499f8 b completed.1
080499e8 W data_start
080485d0 t frame_dummy
U free@@GLIBC_2.0
080486c0 T main
080499f0 d p.0
U printf@@GLIBC_2.0

/***************************************************/

All of the function addresses are offset by several 10's of bytes.
For example
main has is 0x80486e1 in the output, but 080486c0 according to nm.
dummy_function is 0x80486b9 in the output, but nm says 080486a2
and print_trace is 0x8048629 in the output, but 08048604 accordint to
nm.

The discrepencies are 0xe1 - 0xc0 = 33 , 0xb9 - 0xa2 = 23 and
0x29 - 0x04 = 37.

What is the problem? Why don't the addresses agree?

Thanks in Advance

Clark
 
K

Kenneth Brody

[... snip implementation-specific code which shows a backtrace of ...]
[... function calls and reading a symbol table. ...]
/***************************************************/

All of the function addresses are offset by several 10's of bytes.
For example
main has is 0x80486e1 in the output, but 080486c0 according to nm.
dummy_function is 0x80486b9 in the output, but nm says 080486a2
and print_trace is 0x8048629 in the output, but 08048604 accordint to
nm. [...]
What is the problem? Why don't the addresses agree?

Consider what the return address would be. If something in main()
calls free(), should the return address be main() itself, or the
address of something within main()?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
J

jacob navia

I copied this code fragment from http://www.gnu.org/software/libc/manual/html_node/Backtraces.html

#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);

free (strings);
}

/* A dummy function to make the backtrace more interesting. */
void
dummy_function (void)
{
print_trace ();
}

int
main (void)
{
dummy_function ();
return 0;
}


/*************************************************************/
This program produces this output:
Obtained 5 stack frames.
../bin/backtrace2(__gxx_personality_v0+0x149) [0x8048629]
../bin/backtrace2(__gxx_personality_v0+0x1d9) [0x80486b9]
../bin/backtrace2(__gxx_personality_v0+0x201) [0x80486e1]
/lib/libc.so.6(__libc_start_main+0xdd) [0xb7ce00dd]
../bin/backtrace2(__gxx_personality_v0+0x81) [0x8048561]

/**************************************************************/
nm produces this symbol table

080499f4 V DW.ref.__gxx_personality_v0
080498c0 A _DYNAMIC
080499c4 D _GLOBAL_OFFSET_TABLE_
080487f0 R _IO_stdin_used
w _Jv_RegisterClasses
08048604 T _Z11print_tracev
080486a2 T _Z14dummy_functionv
080498b0 d __CTOR_END__
080498ac d __CTOR_LIST__
080498b8 d __DTOR_END__
080498b4 d __DTOR_LIST__
080488a8 r __FRAME_END__
080498bc d __JCR_END__
080498bc d __JCR_LIST__
080499f8 A __bss_start
080499e8 D __data_start
080487a0 t __do_global_ctors_aux
08048590 t __do_global_dtors_aux
080499ec D __dso_handle
080498ac A __fini_array_end
080498ac A __fini_array_start
w __gmon_start__
U __gxx_personality_v0@@CXXABI_1.2
080486eb T __i686.get_pc_thunk.bx
080498ac A __init_array_end
080498ac A __init_array_start
08048750 T __libc_csu_fini
080486f0 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
080499f8 A _edata
080499fc A _end
080487d0 T _fini
080487ec R _fp_hw
080484b8 T _init
08048540 T _start
U backtrace@@GLIBC_2.1
U backtrace_symbols@@GLIBC_2.1
08048564 t call_gmon_start
080499f8 b completed.1
080499e8 W data_start
080485d0 t frame_dummy
U free@@GLIBC_2.0
080486c0 T main
080499f0 d p.0
U printf@@GLIBC_2.0

/***************************************************/

All of the function addresses are offset by several 10's of bytes.
For example
main has is 0x80486e1 in the output, but 080486c0 according to nm.
dummy_function is 0x80486b9 in the output, but nm says 080486a2
and print_trace is 0x8048629 in the output, but 08048604 accordint to
nm.

The discrepencies are 0xe1 - 0xc0 = 33 , 0xb9 - 0xa2 = 23 and
0x29 - 0x04 = 37.

What is the problem? Why don't the addresses agree?

Thanks in Advance

Clark


Obviously because the backtrace is related to where in the function code
you are when the backtrace is called and not where the function starts.

mùain starts at some address, but the call to "dummy function" is 33
bytes into main, and so on.

The best way to verify this hypothesis is to start gdb with your
program and disassemble "main". You should see where the call to the
dummy function is done (it is the first one probably), and see its
address, it should be the same as backtrace reports.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top