Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Feb 2008 15:58:06 +0100
From:      "Harald Servat" <redcrash@gmail.com>
To:        freebsd-hackers@freebsd.org
Subject:   backtrace call comparison
Message-ID:  <d825e0270802110658s510f3347n54a445613ad5df4f@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hello list,

  I'm developing a tool that gathers the callstack information of an
application at certain points. In order to do that, I use the "backtrace"
(and its relative backtrace_symbols) call and I'm mailing you to share some
results, thoughts & possible patches.

  When I compare the behaviour of the backtrace call on a FreeBSD 6.2 box
and on Linux boxes I see that two levels of the callstack are missing.

  Using the example that can be found in
http://www.gnu.org/software/libc/manual/html_node/Backtraces.html I see the
following ( I present three commands here, compilation, run and translation
of addresses using addr2line).

  FreeBSD output:
**
#~/tests/seq/backtrace>gcc bt.c -o bt -rdynamic -g -I/usr/local/include
-L/usr/local/lib/ -lexecinfo

#~/tests/seq/backtrace>./bt
Obtained 3 stack frames.
0x80486b3 <dummy_function+11> at ./bt
0x80486d9 <main+33> at ./bt
0x804856a <_start+118> at ./bt

#~/tests/seq/backtrace>addr2line -e ./bt -f
0x80486b3
dummy_function
/home/harald/tests/seq/backtrace/bt.c:30
0x80486d9
main
/home/harald/tests/seq/backtrace/bt.c:36
0x804856a
_start
??:0

  Linux output:
**
#>gcc -g -rdynamic ./bt.c -o bt

#>./bt
Obtained 5 stack frames.
./bt(print_trace+0x14) [0x8048668]
./bt(dummy_function+0xb) [0x80486e9]
./bt(main+0x15) [0x8048700]
/lib/tls/libc.so.6(__libc_start_main+0xe4) [0x5d4ad4]
./bt [0x80485c5]

#>addr2line -e ./bt -f
0x8048668
print_trace
/home/des/harald/bt.c:14
0x80486e9
dummy_function
/home/des/harald/bt.c:30
0x8048700
main
/home/des/harald/bt.c:36

  On the linux side we can see that there're two additional routines in the
callstack. They're located on 0x8048668 and 0x80485c5. The latter seem to be
related to the "trampoline" to run the application (i.e., to invoke the
main) so I think this can be safely skipped, however the former it's the
print_trace call which in fact is on the callstack but on the FreeBSD
implementation it does not appear on the result.

  Thinking a bit more on this,... A programmer usually knows the routine
that is running when he or she codes the application (unless he or she
starts playing with the callstack manually with jumps and so), so in fact
there's no real need to know the code is on print_trace. To emulate the
Linux behaviour just add on level to the callstack that is the very same
routine (in this case "print_trace").

  So a possible patch for the example could be
       ...
       array[0] = (void*) print_trace;
       size = backtrace (&array[1], 10-1);
       size++;
       ...

  This does not give the same output because each entry of the array buffer
points to the returning address of the callstack whereas array[0] is the
first address of  "print_trace" and not the returning address of backtrace
itself. However it's enough for me.

Regards,
-- 
_________________________________________________________________
Empty your memory,
with a free()...
like a pointer!

If you cast a pointer to an integer,
it becomes an integer,
if you cast a pointer to a struct,
it becomes a struct.

The pointer can crash...,
and can overflow.

Be a pointer my friend...



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?d825e0270802110658s510f3347n54a445613ad5df4f>