This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Backtrace showing different value from stack?
- From: "Philipp Marek" <philipp at marek dot priv dot at>
- To: gcc-help at gcc dot gnu dot org
- Date: Tue, 10 Jun 2008 10:36:47 +0200 (CEST)
- Subject: Backtrace showing different value from stack?
- References:
Hello everybody,
I have a problem in a C program that I just cannot diagnose.
I now suspect that there's some kind of gcc/gdb bug - but maybe you
can tell me (approximately) where I'm wrong.
That's on debian 32bit i686:
ii gcc 4:4.3.0-8 The GNU C compiler
ii gdb 6.8-3 The GNU Debugger
Here's an annotated dump of a GDB session; the commands I
typed into GDB are marked with '>'.
Program start.
The program being debugged has been started already.
Start it from the beginning? (y or n)
Starting program: .../fsvs cp tree/a ggg -d
[Thread debugging using libthread_db enabled]
[New Thread 0xa737f700 (LWP 20128)]
Program crashes with SEGV:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xa737f700 (LWP 20128)]
0xa7e617d2 in free () from /lib/i686/cmov/libc.so.6
in free().
#0 0xa7e617d2 in free () from /lib/i686/cmov/libc.so.6
#1 0x08053fb8 in ops__new_entries (dir=0xa7f47ff4, count=3,
new_entries=0x809e3c8) at est_ops.c:710
#2 0x08065e4a in waa__copy_entries (src=0x809a808, dest=0x809bf48)
at waa.c:2638
#3 0x08065e13 in waa__copy_entries (src=0x809a78c, dest=0x809c0bc)
at waa.c:2631
#4 0x0804f579 in cm___make_copy (root=0xaffb96dc, cp_src=0x8099bc2 "tree/a",
revision=0, cp_dest=0x8099bdf "ggg", paths_are_wc_relative=1)
at cp_mv.c:1240
#5 0x0805013f in cm__work (root=0xaffb96dc, argc=2, argv=0xaffb980c)
at cp_mv.c:1392
(Maybe pointer used as a local variable, due to optimization - doesn't matter,
I think.)
#6 0x08056a70 in main (argc=5, args=0xaffb9804, env=
Cannot access memory at address 0x8
) at fsvs.c:1240
> up
#1 0x08053fb8 in ops__new_entries (dir=0xa7f47ff4, count=3,
new_entries=0x809e3c8) at est_ops.c:710
710 IF_FREE(dir->by_name);
IF_FREE is a macro, "do { if (x) free(x); x=NULL; } while (0)".
This calls free().
The offending parameter is the first, "dir" resp. "dest":
> print dir
$5 = (struct estat *) 0xa7f47ff4
But the caller has:
> up
#2 0x08065e4a in waa__copy_entries (src=0x809a808, dest=0x809bf48)
at waa.c:2638
2638 STOPIF( ops__new_entries(dest, append_count, to_append), NULL);
And here the pointer is still correct (verified *dest, too):
> print dest
$6 = (struct estat *) 0x809bf48
The stack dump confirms that, looks good and reasonable:
> print /x *(int*)$esp @ 40
$7 = {0x809bf48, 0x3, 0x809e3c8, 0x0, 0x809abe8, 0x809e3b8, 0x0, 0x0,
=========> dest, count, to_append
0x809e3c8, 0x3, 0xfb9590b9, 0xc49ee9af, 0x580a, 0x1, 0x809bfc4, 0x0,
0x809e398, 0x3, 0xaffb9608, 0x8065e13, 0x809a808, 0x809bf48, 0x8099ea8,
0x8099ea8, 0x809c2a8, 0x0, 0xaffb9608, 0x80574f9, 0x809e398, 0x3,
0xfb95e0b9, 0xc44ee9af, 0x580a, 0x3, 0x809bf48, 0x0, 0x8099bc2, 0x0,
0xaffb9658, 0x804f579}
But GDB at least gives me another value:
> down
#1 0x08053fb8 in ops__new_entries (dir=0xa7f47ff4, count=3,
new_entries=0x809e3c8) at est_ops.c:710
710 IF_FREE(dir->by_name);
Here the stack dump is a bit more complicated:
> print /x *(int*)$esp @ 40
$8 = {0x15683e9f, 0x809becc, 0xfb9540b9, 0xc4eee9af, 0x580a, 0x0, 0x0, 0x0,
0x809e3d4, 0x0, 0xaffb95b8, 0x8065e4a, 0x809bf48, 0x3, 0x809e3c8, 0x0,
============================================> dest count to_append
0x809abe8, 0x809e3b8, 0x0, 0x0, 0x809e3c8, 0x3, 0xfb9590b9, 0xc49ee9af,
0x580a, 0x1, 0x809bfc4, 0x0, 0x809e398, 0x3, 0xaffb9608, 0x8065e13,
0x809a808, 0x809bf48, 0x8099ea8, 0x8099ea8, 0x809c2a8, 0x0, 0xaffb9608,
0x80574f9}
But I cannot even find the value that GDB reports for dir.
As I don't have any other idea I turn to the disassembler listing:
> disas
Dump of assembler code for function ops__new_entries:
0x08053f9b <ops__new_entries+0>: push %ebp
0x08053f9c <ops__new_entries+1>: mov %esp,%ebp
0x08053f9e <ops__new_entries+3>: push %edi
0x08053f9f <ops__new_entries+4>: push %esi
0x08053fa0 <ops__new_entries+5>: push %ebx
0x08053fa1 <ops__new_entries+6>: sub $0xc,%esp
0x08053fa4 <ops__new_entries+9>: cld
Fetch "dir" parameter:
0x08053fa5 <ops__new_entries+10>: mov 0x8(%ebp),%ebx
Fetch "by_name" member
0x08053fa8 <ops__new_entries+13>: mov 0x50(%ebx),%eax
Tests for NULL:
0x08053fab <ops__new_entries+16>: test %eax,%eax
0x08053fad <ops__new_entries+18>: je 0x8053fbb <ops__new_entries+32>
[- 0x08053faf <ops__new_entries+20>: sub $0xc,%esp
[ 0x08053fb2 <ops__new_entries+23>: push %eax
Calls free() and crashes.
[ 0x08053fb3 <ops__new_entries+24>: call 0x804aab4 <free@plt>
[- 0x08053fb8 <ops__new_entries+29>: add $0x10,%esp
0x08053fbb <ops__new_entries+32>: movl $0x0,0x50(%ebx)
...
> q
Quit
The program is running. Exit anyway? (y or n)
BTW, the marked lines are a bit strange - why is esp changed twice?
gcc-3.3 doesn't do that (just a single "addl $4,%esp"), but crashes the same.
Can somebody shed some light on this mystery?
I believe that I'm just a bit off the track, to see some obvious clue.
Note: it's entirely possible that I'm trashing the stack somewhere. I'd
just like to know why GDB shows something different for "bt" and the
"manual" stack dump.
Thank you very much for all ideas.
Regards,
Phil