Отсутствуют номера строк из символов отладки для библиотеки во всей программе, но не отдельно

Я вижу странную проблему при попытке использовать gdb для отладки тестовой программы для пакета, созданного с помощью libtool. Если я запущу libtool --mode=execute gdb .libs/libfoo.so и попрошу его указать исходный код какой-либо функции list Bar::Baz, я получу исходный код, как и ожидалось. Если я запускаю libtool --mode=execute gdb binary, я могу взломать Bar::Baz() и увидеть его аргументы в трассировке стека, но я не получаю исходный файл или номера строк, например:

#7  0x018348e5 in Bar::Baz(Qux*, Quux*) () from /path/to/libfoo.so
                           ^^^^^^^^^^^ <--- debug symbols are present!

Точно так же, если я попытаюсь list Bar::Baz при отладке исполняемого файла, я получаю

No line number known for 'Bar::Baz'.

Я подтвердил, что двоичный файл связан с -g, и я могу перечислить его функцию main, поэтому я знаю, что присутствует некоторая отладочная информация.

Когда я говорю info sources, я получаю полный список файлов, из которых построена библиотека, с правильными абсолютными путями. Когда я говорю info shared, я получаю правильный путь к объектному файлу с Yes в столбце Syms.

Любые дополнительные идеи, что может пойти не так, и как это исправить?


Редактировать 1: случайно я запустил objdump -g в проблемной библиотеке и получил следующий вывод:

/path/to/foo.so.0.0.0: file format elf32-i386
objdump: /path/to/foo.so.0.0.0: no recognized debugging information

Это удивительно, так как objdump -h (то, что я пытался запустить) перечисляет кучу .debug_* разделов. Руководство objdump также предлагает readelf -w, и это, кажется, печатает огромную кучу информации. Однако мне нужно посмотреть, что он на самом деле предоставляет.


Редактировать 2: Итак, readelf -w произвел некоторое просветление. По какой-то причине общий объектный файл не содержит отладочной информации от подавляющего большинства любого из связанных с ним объектов. На основании файлов Makefile возможно, что команда, которая фактически собирает объекты в разделяемую библиотеку, не передается -g, и поэтому информация не распространяется должным образом. Самое смешное, что это работает (имеет полную отладочную информацию) на всех других наших конфигурациях, включая ту же версию компилятора на x86_64 (по сравнению с нынешней x86).


Редактировать 3: На самом деле прошел полную перестройку с измененным Makefile с добавлением -g в LDFLAGS, и это не имело никакого значения. Теперь я хорошо и действительно сбит с толку.


person Phil Miller    schedule 21.07.2011    source источник


Ответы (3)


Это ответ на старый вопрос, но ваша проблема совпала с моей, но ни одно из решений не сработало. Вот что сработало для меня.

Измените CFLAGS -g на "-g -gstabs".

objdump не распознавал отладочную информацию в стиле карлика. -gstabs меняет этот формат на тот, который работает с objdump -g и objdump -S и моим отладчиком.

Надеюсь, поможет.

ПРИМЕЧАНИЕ. Для себя я собирал ядро ​​Linux. Это изменение было сделано в Makefile ядра Linux.

person sleeves    schedule 04.11.2011
comment
Недавно я столкнулся с повторением этого вопроса. На этот раз это был gcc 4.9 против gdb 7.2. Компилятор генерировал DWARF v4, в то время как отладчик мог понять только до DWARF v3. Обновление отладчика решило это. В качестве обходного пути передача -gdwarf-3 сказала ему выдать старый символ формата. - person Phil Miller; 07.02.2017

Ваша первая путаница: Bar::Baz(Qux*, Quux*) не означает, что символы отладки присутствуют (и фактически подразумевает, что они отсутствуют).

Отладчик просто искажает имя функции. Если бы символы отладки действительно присутствовали, вы бы увидели Bar::Baz(Qux* qux = 0x12..., Quux* quux = 0x234...)

Что касается реальной проблемы, я подозреваю, что символ определен в какой-то другой библиотеке, которая

  • появляется в строке ссылки для двоичного файла раньше, чем libfoo.so, и
  • был построен без символов отладки

(Загрузчик времени выполнения свяжет ссылку на Bar::Baz() с первым определением, которое он увидит.)

Если вы напечатаете ip в кадре №7, а затем сделаете info symbol <value-just-printed>, я подозреваю, что у вас будет "Ага!" момент.

EDIT: Ваше обновление сделало ваш вопрос противоречивым. АФАИКТ,

  1. gdb может видеть символы отладки при выполнении
    libtool --mode=execute gdb .libs/libfoo.so
  2. но не при выполнении libtool --mode=execute gdb binary
  3. вы убедились, что определение символа взято из точно того же .libs/libfoo.o
  4. и readelf -w не видит символы отладки в .libs/libfoo.o

По крайней мере, одно из приведенных выше утверждений, скорее всего, неверно.

Если все они действительно верны, у вас, вероятно, странная ошибка GDB и readelf (возможна ошибка в одном, одновременная ошибка в обоих несколько маловероятна).

Также обратите внимание, что добавлять -g к LDFLAGS, как правило, неправильно. Вы хотели вместо этого добавить его в CXXFLAGS?

person Employed Russian    schedule 21.07.2011
comment
Это хорошее замечание по поводу искажения имени. Завтра утром я повнимательнее рассмотрю, что именно связано. Я сомневаюсь, что задействована неправильная библиотека, поскольку двоичный файл представляет собой тестовую программу, построенную в том же дереве, что и единственный видимый экземпляр библиотеки, которую он должен тестировать - нет системных установок или чего-то подобного, с чем можно было бы бороться. . - person Phil Miller; 21.07.2011
comment
Я только что проверил это, и связанная библиотека - это библиотека, которую я ожидаю. Допущенная мною опечатка привела к интересному открытию, которым я исправлю первоначальный вопрос. - person Phil Miller; 21.07.2011
comment
Если у вас (или у кого-то еще, кто читает это) есть другие идеи, я весь внимание (на самом деле, глаза). - person Phil Miller; 23.07.2011

Что-то заставило меня задуматься о том, что выводит show language, когда у вас возникают проблемы. Если это не c++, может быть, нужно set language c++?

person matt    schedule 31.07.2011