Ошибки в инструментальной цепочке (компилятор / отладчик)? - PullRequest
0 голосов
/ 12 сентября 2011

Что-то ужасно не так с gdb, gcc или с обоими, и я не знаю что.Я создал POC для воспроизведения на gcc (GCC) 4.6.1 20110819 (prerelease) и GNU gdb (GDB) 7.3.50.20110908-cvs - да, это версия CVS, потому что я столкнулся с этой проблемой http://sourceware.org/bugzilla/show_bug.cgi?id=12435,, однако я также тестировал с GNU gdb (GDB) 7.3.1 ион ведет себя так же.

Теперь в POC: https://gist.github.com/1211017 проблема может наблюдаться в строке 33

По моему мнению, *c->foos[i] следует оценить по адресуi-й foo, как показано в строке 21. Но исполняемый файл вылетает, как вы можете видеть в выводе.

Кто-нибудь знает, что не так?Было бы желательно получить объяснение на уровне ASM или внутренних органов GCC.

Приложение :

  1. Структуры данных не могут изменяться - они не могутпринадлежат моему коду, я должен взаимодействовать с ними.
  2. Код *c->foos[i], используемый для работы с более старыми версиями gcc.
  3. dump_container должен иметь в качестве параметра a container* -эта функция также не принадлежит моему коду

Также стоит упомянуть: *c->foos[i] используется для работы.

Ответы [ 3 ]

3 голосов
/ 12 сентября 2011

Запуск вашего кода через всегда полезный valgrind говорит:

==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== 

Я предполагаю, что вы найдете ошибку в своем собственном коде, а не в компиляторе или отладчике.

РЕДАКТИРОВАТЬ Или, поскольку вы хотите, чтобы я разъяснил это для вас, измените строку 33 на

printf("foo[%d]=%d at %p\n", i, (*c->foos)[i]->i, (void*) (*c->foos)[i]);
1 голос
/ 12 сентября 2011

Я не понимаю, как * c-> foos [i] работал бы когда-либо, c->foos дает указатель на массив (указатель на блок указателей) (указателей), согласно строке 43,при выполнении c->foos[i] вы не обращаетесь к элементу массива.(*c->foos)[i] должно работать ...

Взгляните на таблицу приоритетов операторов C .

0 голосов
/ 12 сентября 2011

На мой взгляд, * c-> foos [i] следует оценить по адресу i-го foo, как показано в строке 21.

Нет. Если это то, что вы имеете в виду, вы должны использовать &c->foos[i]. Ваша версия разыменовывает i-тый foo, что легко может привести к

Но исполняемый файл вылетает, как вы можете видеть в выводе.

.

...