Трассировка стека отладчика GCC отображает неправильное имя файла и номер строки

Я пытаюсь перенести довольно большой проект C++ на использование g ++ 4.0 в Mac OS X. Мой проект компилируется без ошибок, но я не могу заставить GDB работать должным образом. Когда я смотрю на стек, набирая «bt» в командной строке GDB, все отображаемые имена файлов и номера строк неверны.

Например, согласно трассировке стека GDB, моя main() функция должна находиться в stdexcept из Mac OS X SDK, что не имеет никакого смысла.

Что могло вызвать такую ​​серьезную неисправность GDB? Я уже проверил в своем коде операторы #line и #file и убедился, что в коде есть только окончания строк unix. Я также очистил и перестроил проект. Я также пробовал отлаживать проект Hello World, и у него не было такой проблемы.

Может ли проблема быть связана с одной из сторонних библиотек, на которые я ссылаюсь, и с тем, как они скомпилированы? Или это что-то совсем другое?

Вот два примерных вызова gcc и ld выполняемых Xcode . AFAIK все cpp-файлы в моем проекте скомпилированы и связаны с одинаковыми параметрами.

/Developer/usr/bin/gcc-4.0 -x c ++ -arch i386 -fmessage-length = 0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -O0 -fpermissive -Wreturn-type -Wunused-variable -DNO_BASS_SOUND -D_DEBUG -DXCODE -D__WXMAC__ -isysroot /Developer/SDKs/MacOSX10.5.sdk -mfix-and-continue -fvisibility-inlines-hidden -mmacosx-version-min = 10.4 -gdwarf-2 -D_FILE_OFFSET_DILBITS -D_FILE_OFFSET_DILBITS -D_FILE_OFFSET_DILBITS = 64 -D__WXMAC__ -c "/ Users / adriangrigore / Documents / Gemsweeper Mac / TSDLGameBase.cpp" -o "/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Gemsweeper Mac.build/Debug/Gemsweeper Mac.build/Objects-normal/ i386 / TSDLGameBase.o "

/Developer/usr/bin/g++-4.0 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk "-L / Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug" -L / Developer / SDKs / MacOSX10 .5.sdk / usr / local / lib -L / opt / local / lib "-F / Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug" -F / Users / adriangrigore / Library / Frameworks -F / Developer / SDK / MacOSX10.5.sdk / Library / Frameworks -filelist "/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Gemsweeper Mac.build/Debug/Gemsweeper Mac.build/Objects-normal/i386/Gemsweeper Mac.LinkFileList" - mmacosx-version-min = 10.4 /opt/local/lib/libboost_program_options-mt.a /opt/local/lib/libboost_filesystem-mt.a /opt/local/lib/libboost_serialization-mt.a / opt / local / lib / libboost_system-mt.a /opt/local/lib/libboost_thread-mt.a "/ Users / adriangrigore / Documents / Gemsweeper Mac / сторонняя / FreeImage / Dist / libfreeimage.a "" / Users / adriangrigore / Documents / Gemsweeper Mac / 3rd party / cpuinfo-1.0 / libcpuinfo.a "-L / usr / local / lib -framework IOKit -framework Carbon -framework Cocoa -framework System -framework QuickTime -framework OpenGL -framework AGL -lwx_macd_richtext-2.8 -lwx_macd_aui-2.8 -lwx_macd_xrc-2.8 -lwx_macd_macd_qa -lwx_base_carbond_xml-2.8 -lwx_base_carbond_net-2.8 -lwx_base_carbond-2.8 -framework SDL -framework Cocoa -o "/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug / Gemsweeper Mac.appOS/Contents/Max"-L / usr / local / lib -framework IOKit -framework Carbon -framework Cocoa -framework System -framework QuickTime -framework OpenGL -framework AGL -lwx_macd_richtext-2.8 -lwx_macd_aui-2.8 -lwx_macd_xrc_2.8 -lwq_mac_mac_2.8 -lwq_mac_mac_2.8 -lwq_mac_mac_2.8 lwx_macd_adv-2.8 -lwx_macd_core-2.8 -lwx_base_carbond_xml-2.8 -lwx_base_carbond_net-2.8 -lwx_base_carbond-2.8 -framework SDL -framework Cocoa -o "/ Users / adriangrigorewee / Gemsapps / GeoSoft / GeoSoft / Geforce / Debian / Debian / Debian / Debian / Debian / Debian / Debian / Debian / Debugments / GeoSoft / GeoSoft / GeoSoft / GeoS. / Gemsweeper Mac "-L / usr / local / lib -framework IOKit -framework Carbon -framework Cocoa -framework System -framework QuickTime -framework OpenGL -framework AGL -lwx_macd_richtext-2.8 -lwx_macd_aui-2.8 -lwx_macd_xrc_2.8 -lwq_mac_mac_2.8 -lwq_mac_mac_2.8 -lwq_mac_mac_2.8 lwx_macd_adv-2.8 -lwx_macd_core-2.8 -lwx_base_carbond_xml-2.8 -lwx_base_carbond_net-2.8 -lwx_base_carbond-2.8 -framework SDL -framework Cocoa -o "/ Users / adriangrigorewee / Gemsapps / GeoSoft / GeoSoft / Geforce / Debian / Debian / Debian / Debian / Debian / Debian / Debian / Debian / Debugments / GeoSoft / GeoSoft / GeoSoft / GeoS. / Gemsweeper Mac "8 -framework SDL -framework Cocoa -o "/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug / Gemsweeper Mac.app/Contents/MacOS/Gemsweeper Mac"8 -framework SDL -framework Cocoa -o "/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug / Gemsweeper Mac.app/Contents/MacOS/Gemsweeper Mac"

Обратите внимание, что я уже задавал аналогичный вопрос относительно отладчика Xcode здесь , но я делаю репост, поскольку только что узнал, что это на самом деле не ошибка Xcode, а проблема с GCC / ld / GDB.

Изменить: в моем проекте используются следующие сторонние библиотеки: SDL , Boost , wxWidgets . Я не уверен, имеет ли это значение для этой проблемы, но я просто хотел упомянуть об этом на всякий случай.

Я попытался скомпилировать шаблон проекта Xcode SDL и не испытал такой же проблемы, так что это должно быть связано с чем-то особенным в моем проекте.

Второе редактирование : как я только что узнал, я совершил ошибку при поиске файлов со строкой «Это автоматически сгенерировано». Я только что нашел несколько десятков файлов с одной и той же строкой, все принадлежащие FreeImage , одной из сторонних библиотек, которые я использую. Итак, проблема, похоже, связана с FreeImage, но я все еще не знаю, как действовать.

Ответов (11)

Вы компилируете с включенной оптимизацией? Я обнаружил, что O2 или более поздняя версия немного путается с символами, что делает файлы gdb и core практически бесполезными.

Также убедитесь, что вы компилируете с параметром -g.

У меня были эти симптомы, когда моя версия gdb не соответствовала моей версии g ++.

Попробуйте установить самую новую версию GDB.

Я попытался скомпилировать шаблон проекта XCode SDL и не столкнулся с той же проблемой, так что это должно быть связано с чем-то особенным в моем проекте.

Верный. Настройки вашего проекта - это совсем другое.

Вам нужно будет отключить оптимизацию отладки в настройках проекта Xcode для отладочной сборки. К сожалению, Xcode заставляет GDB переходить к странным строкам (не по порядку), когда вы ожидаете, что он будет двигаться последовательно.

Зайдите в настройки вашего проекта. Установите следующие

1) Instruction Scheduling   = None
2) Optimization Level       = None [-O0]
3) ZERO_LINK                = None

Ваши проблемы должны исчезнуть после этого. Вот экран настроек проекта, на котором вам нужно изменить настройки:

альтернативный текст

Смотрите мой ответ здесь

Я скачал и скомпилировал исходники FreeImage, и да, файл b44ExpLogTable.cpp скомпилирован в libfreeimage.a . Проблема выглядит так, как будто сценарий gensrclist.sh просто собирает все .cpp файлы, не пропуская тот, у которого есть основной вход. Этот сценарий генерирует файл с именем, Makefile.srcs но один уже предоставлен. (запустить его на моем Leopard не удалось, некоторые проблемы с sh - он работал, если я перешел sh на bash )

Прежде чем вы что-либо измените, это дает a.out

c++ libfreeimage.a

Файл Makefile.srcs уже создан, поэтому вы сможете удалить b44ExpLogTable.cpp из него файл . Тогда сделай

make -f Makefile.osx clean
make -f Makefile.osx

Когда это будет сделано, приведенное выше c++ libfreeimage.a должно привести к следующей ошибке

Undefined symbols:
  "_main", referenced from:
      start in crt1.10.5.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

В ваших файлах cpp обязательно есть символы отладки ( -gdwarf-2 опция).

Вы используете отдельный файл dSYM для отладочных символов? Или они внутри объектных файлов. Сначала я бы попытался использовать DWARF в файлах dSYM и посмотреть, помогает ли это (или наоборот)

Сторонние библиотеки кажутся сборками релизов (если, конечно, вы не переименовали их сами), например, я точно знаю, что boost использует -d monniker в именах библиотек для обозначения библиотек отладки (например libboost_filesystem-mt-d.a ).

Теперь это не должно создавать проблемы, это просто должно означать, что вы не можете вмешиваться в вызовы сторонних библиотек. (по крайней мере, не имейте никакого смысла, когда вы это делаете;) Но поскольку у вас есть проблемы, возможно, стоит попытаться связать с отладочными версиями этих библиотек ...

В качестве теста вы можете проверить, дает ли addr2line ожидаемые значения. Если так, это будет означать, что нет ничего плохого в ELF, сгенерированном вашими параметрами компиляции / компоновки, и бросает все подозрения на GDB. Если нет, то подозрение по-прежнему присутствует как в инструментах, так и в файле ELF.

Неужели вы используете SDL? SDL переопределяет, main так что ваш main будет иметь имя SDL_main и что части SDL могут быть сильно оптимизированы, поэтому у вас будут проблемы с получением хорошего вывода gdb.

...просто мысль

Прочитай это

Из ваших флагов отладочная информация должна быть в объектных файлах.

Создает ли настройки вашего проекта исполняемый файл в одном месте, а затем перемещает ли последний исполняемый файл в другое место по завершении? Если это так, то GDB может не находить файлы объектов и, следовательно, неправильно извлекать отладочную информацию из объектных файлов.

Просто догадка.

Я столкнулся с этим несколько лет назад при переходе с компиляторов Codewarrior на Xcode. Я считаю, что способ обойти это - поставить флаг " -fno-inline-functions " в других флагах C (только для разработчиков).

Для нас эта проблема была более выражена в архитектуре PowerPC.

Что если вы удалите флаги «-fvisibility-inlines-hidden» и «-mfix-and-continue»?

У меня никогда не было возможности «исправить и продолжить» должным образом.

WxWidgets также определяют свои собственные, main если вы используете их IMPLEMENT_APP() макрос

От сюда

Как и во всех программах, обязательно должна быть «основная» функция. В wxWidgets main реализуется с помощью этого макроса, который создает экземпляр приложения и запускает программу.

IMPLEMENT_APP(MyApp)

У меня есть обновка, которую ты можешь попробовать.

Прямо перед своим main вы можете написать

#ifdef main
#  error main is defined
#endif

int main(int argc, char *argv[]) {

это должно выдать ошибку, если у вас есть переопределяющий заголовок main .

Если вы определите собственное, вы можете получить предупреждение, где было сделано предыдущее определение.

#define main foo

int main(int argc, char *argv[]) {

Вы также можете попробовать как undef раз перед вашим main

#undef main

int main(int argc, char *argv[]) {