开发者

Bug(s) in the toolchain (compiler/debugger)?

There is something terribly wrong with either gdb, gcc or both, and I don't know what. I've created开发者_如何学运维 a POC to reproduce it on gcc (GCC) 4.6.1 20110819 (prerelease) and GNU gdb (GDB) 7.3.50.20110908-cvs - yes, this is the CVS version, because I was running into this issue http://sourceware.org/bugzilla/show_bug.cgi?id=12435, however I've also tested with GNU gdb (GDB) 7.3.1 and it behaves the same.

Now to the POC: https://gist.github.com/1211017 the problem can be observed on line 33

In my opinion, *c->foos[i] should evaluate to the address of the i-th foo, as displayed by line 21. But the executable crashes, as you can see in the output.

Does anyone know what is wrong? An explanation at either the ASM level or GCC internals would be welcome.

Addendum:

  1. The data structures are not allowed to change - they don't belong to my code, I have to interoperate with them.
  2. The code *c->foos[i] used to work with older versions of gcc.
  3. dump_container must have as parameter a container* - this function doesn't belong to my code either

Also worth mentioning: *c->foos[i] used to work.


Running your code through the ever helpful valgrind says:

==16066== Use of uninitialised value of size 8
==16066==    at 0x40061B: dump_container (bug.c:33)
==16066==    by 0x400726: main (bug.c:49)
==16066== 
==16066== Invalid read of size 4
==16066==    at 0x400620: dump_container (stdio2.h:105)
==16066==    by 0x400726: main (bug.c:49)
==16066==  Address 0x89485ed18949ed39 is not stack'd, malloc'd or (recently) free'd
==16066== 
==16066== 
==16066== Process terminating with default action of signal 11 (SIGSEGV)
==16066==  General Protection Fault
==16066==    at 0x400620: dump_container (stdio2.h:105)
==16066==    by 0x400726: main (bug.c:49)
==16066== 

My guess is that you'll find the bug in your own code rather than the compiler or debugger.

EDIT Or since you want me to spell it out for you, change line 33 to

printf("foo[%d]=%d at %p\n", i, (*c->foos)[i]->i, (void*) (*c->foos)[i]);


I don't understand how *c->foos[i] would have ever worked, c->foos gives a pointer to an array (a pointer to a bloc of pointers) (of pointers), according to line 43, when doing c->foos[i] you're not accessing to an element of the array. (*c->foos)[i] should work...

Take a look at the C Operator Precedence Table.


In my opinion, *c->foos[i] should evaluate to the address of the i-th foo, as displayed by line 21.

No. If that is what you mean, you should use &c->foos[i]. Your version dereferences the i-th foo, what easily can lead to

But the executable crashes, as you can see in the output.

.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜