This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Backtrace showing different value from stack?


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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]