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