[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: problem with backtrace() after system update



Pierre Habouzit wrote:
On Wed, Jan 13, 2010 at 01:01:27PM +0100, Bartek 'BaSz' Szurgot wrote:
Aurelien Jarno wrote:
Bartek 'BaSz' Szurgot a écrit :
hi,
Hi,

some time ago i wrote C++ code to save backtrace in a vector of
strings. it worked fine until one of system updates (~month
ago), when it suddenly started to show too short listening(s).
i've tried example from manual (man backtrace) to verify this,
and it does not work properly too. example output is:

$ gcc -Wall -g3 -rdynamic main.c && ./a.out 10
backtrace() returned 4 addresses
./a.out(_Z7myfunc3v+0x1c) [0x400b28]
./a.out [0x400ba9]
./a.out(_Z6myfunci+0x23) [0x400bce]
./a.out(_Z6myfunci+0x1c) [0x400bc7]

where there should be >10 calls on stack. raising number given
as an argument does not change output.
What are the missing entries you expect?
in the man's example function myFunc() is recurrent. here it should be
call 10 times. this is its body taken from man:
void myfunc(int ncalls)
{
  if (ncalls > 1)
    myfunc(ncalls - 1);
  else
    myfunc2();
}

example output provided in man does show more calls to myFunc() (i.e. 3):

$ cc -rdynamic prog.c -o prog
$ ./prog 3
backtrace() returned 8 addresses
./prog(myfunc3+0x5c) [0x80487f0]
./prog [0x8048871]
./prog(myfunc+0x21) [0x8048894]
./prog(myfunc+0x1a) [0x804888d]
./prog(myfunc+0x1a) [0x804888d]
./prog(main+0x65) [0x80488fb]
/lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c]
./prog [0x8048711]

gcc does tail-recursion optimization, hence in the previous code it's
normal to have a short backtrace.

i did little testing and you're right. i made a bit more complicated (no tail-recursion) function and it indeed provided expected backtrace:

int myfunc(int ncalls, int tmp)
{
  if(ncalls==0)
  {
    myfunc2();
    return tmp%3;
  }

  int a;
  if(tmp%3)
    a=myfunc(ncalls-1, tmp+1);
  else
    a=myfunc(ncalls-1, tmp+2);

  return a+tmp;
}


$ gcc -Wall -g3 -rdynamic -pg backtrace.c && ./a.out 10
backtrace() returned 12 addresses
./a.out(myfunc3+0x21) [0x400c5d]
./a.out [0x400ce3]
./a.out(myfunc+0x1e) [0x400d03]
./a.out(myfunc+0x9b) [0x400d80]
./a.out(myfunc+0xb1) [0x400d96]
./a.out(myfunc+0x9b) [0x400d80]
./a.out(myfunc+0xb1) [0x400d96]
./a.out(myfunc+0x9b) [0x400d80]
./a.out(myfunc+0xb1) [0x400d96]
./a.out(myfunc+0x9b) [0x400d80]
./a.out(myfunc+0xb1) [0x400d96]
./a.out(myfunc+0x9b) [0x400d80]

i was completely unaware that gcc does such optimizations in debug (-g3) mode... :/

thank you for your help!
i think it's good idea to update backtrace()'s manual.

btw:
i wondered how will original program (with tail-recursion) look under debugger. it looks strange, since gdb's stack and one returned by backtrace() differ. :/

$ gdb ./a.out
GNU gdb (GDB) 7.0-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/a.out...done.
(gdb) b 15
Breakpoint 1 at 0x400a57: file backtrace.c, line 15.
(gdb) r 10
Starting program: /tmp/a.out 10

Breakpoint 1, myfunc3 () at backtrace.c:15
15        nptrs = backtrace(buffer, SIZE);
(gdb) bt
#0  myfunc3 () at backtrace.c:15
#1  0x0000000000400ae9 in myfunc2 () at backtrace.c:35
#2  0x0000000000400b04 in myfunc (ncalls=0, tmp=21) at backtrace.c:42
#3  0x0000000000400b49 in myfunc (ncalls=1, tmp=19) at backtrace.c:50
#4  0x0000000000400b49 in myfunc (ncalls=2, tmp=17) at backtrace.c:50
#5  0x0000000000400b49 in myfunc (ncalls=3, tmp=15) at backtrace.c:50
#6  0x0000000000400b49 in myfunc (ncalls=4, tmp=13) at backtrace.c:50
#7  0x0000000000400b49 in myfunc (ncalls=5, tmp=11) at backtrace.c:50
#8  0x0000000000400b49 in myfunc (ncalls=6, tmp=9) at backtrace.c:50
#9  0x0000000000400b49 in myfunc (ncalls=7, tmp=7) at backtrace.c:50
#10 0x0000000000400b49 in myfunc (ncalls=8, tmp=5) at backtrace.c:50
#11 0x0000000000400b49 in myfunc (ncalls=9, tmp=3) at backtrace.c:50
#12 0x0000000000400b49 in myfunc (ncalls=10, tmp=1) at backtrace.c:50
#13 0x0000000000400bb4 in main (argc=2, argv=0x7fffffffe458) at backtrace.c:62
(gdb) c
Continuing.
backtrace() returned 4 addresses
/tmp/a.out(myfunc3+0x1c) [0x400a68]
/tmp/a.out [0x400ae9]
/tmp/a.out(myfunc+0x19) [0x400b04]
/tmp/a.out(myfunc+0x5e) [0x400b49]

Program exited normally.
(gdb)

--
pozdrawiam serdecznie / best regards,
Bartek 'BaSz' Szurgot

Wroclaw Centre for Networking and Supercomputing
Wroclaw University of Technology,
pl. Grunwaldzki 9, D2/101,
50-377 Wroclaw
http://www.wcss.wroc.pl

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


Reply to: