Как я могу узнать, была ли библиотека скомпилирована с помощью -g?

105

У меня есть несколько скомпилированных библиотек на x86 Linux, и я хочу быстро определить, были ли они скомпилированы с отладочными символами.

Дэн Хук
источник

Ответы:

86

Если вы работаете в Linux, используйте objdump --debugging. Для каждого объектного файла в библиотеке должна быть запись. Для объектных файлов без символов отладки вы увидите что-то вроде:

objdump --debugging libvoidincr.a
In archive libvoidincr.a:

voidincr.o:     file format elf64-x86-64

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

Мэтт Макклеллан
источник
5
Также есть obdjump -W libи readelf -w lib. Последний вариант более настраиваемый - см. Справочную страницу readelf (1).
przemoc 04
3
Для любого двоичного файла (включая те, которые скомпилированы с помощью -g) objdump дает мне ответ «нет распознанной отладочной информации», если я не скомпилирую его с помощью -gstabs. Кажется, это распознанная ошибка.
Дэн Хук,
Дэн, на какой платформе вы это пробовали?
swegi 04
Используемый русский язык: от man objdump (1) флаг --debugging "пытается проанализировать информацию о форматах отладки STABS и IEEE, хранящуюся в файле, и распечатать ее с использованием синтаксиса, подобного C. Если ни один из этих форматов не найден, эта опция возвращается в опции -W, чтобы распечатать любую информацию DWARF в файле ».
Мэтт Макклеллан
5
objdump -gничего не дает для простого test.o, скомпилированного как с, так и без g, что делает его практически бесполезным. Ubuntu 12.04, gcc 4.6.3, GNU objdump 2.22. nm -aкажется более полезным.
jw013
89

Предлагаемая команда

objdump --debugging libinspected.a
objdump --debugging libinspected.so

дает мне всегда один и тот же результат, по крайней мере, на Ubuntu / Linaro 4.5.2:

libinspected.a:     file format elf64-x86-64
libinspected.so:     file format elf64-x86-64

независимо от того, была ли создана архивная / общая библиотека с -gопцией или без нее

Что действительно помогло мне определить, -gиспользовался ли инструмент, так это инструмент readelf :

readelf --debug-dump=decodedline libinspected.so

или

readelf --debug-dump=line libinspected.so

Это распечатает набор строк, состоящий из исходного имени файла, номера строки и адреса, если такая отладочная информация включена в библиотеку , иначе он ничего не напечатает .

Вы можете передать любое значение, которое сочтете необходимым для --debug-dumpoption вместо decodedline.

Алекс ИнТехно
источник
1
работает отлично. Я попробовал эту команду на своем исполняемом файле с первым CMAKE_BUILD_TYPE RELEASE, и команда вернула пустую. Затем я попробовал с CMAKE_BUILD_TYPE DEBUG, и тогда было довольно много вывода.
написано в инфо-журнале
33

Что помогло:

gdb mylib.so

Он печатает, когда символы отладки не найдены:

Reading symbols from mylib.so...(no debugging symbols found)...done.

Или при обнаружении:

Reading symbols from mylib.so...done.

Ни один из предыдущих ответов не дал для меня значимых результатов: библиотеки без символов отладки давали много результатов и т. Д.

Велкан
источник
Спасибо! Это сработало для меня, используя компилятор clang в Android с cmake :)
Пэр Нильс Амсен,
супер отлично подходит для быстрой проверки! также работает с объектными файлами * .o.
Стефан Роллан,
28

nm -a <lib> распечатает все символы из библиотеки, в том числе отладочные.

Таким образом, вы можете сравнить выходные данные nm <lib>и nm -a <lib>- если они отличаются, ваша библиотека содержит некоторые символы отладки.

qrdl
источник
3
@ Занятые русские. Не могли бы вы подробнее рассказать об этом? Как вы думаете, почему это неправильный инструмент? Он выполняет свою работу, как и в Linux.
qrdl 05
Даже для Embedded linux на базе ядра 2.6.35, xxx-objdump, xxx-nm работает нормально.
agfe2
nm -aимеет псевдоним, nm --debug-symsкоторый не требует пояснений :-).
pevik
3
Просто введите, diff <(nm <lib>) <(nm -a <lib>)чтобы получить простую
разницу
17

В OSX вы можете использовать dsymutil -sи dwarfdump.

При использовании dsymutil -s <lib_file> | moreвы увидите пути к исходным файлам в файлах, которые имеют символы отладки, но в противном случае только имена функций.

Glennr
источник
11
Можете ли вы пояснить, что искать, например, в выводе dsymutil -s? Означает ли существование вывода, что он был построен с использованием символов отладки, или его нужно использовать с помощью grep?
Митч
12

Вы можете использовать objdump для этого .

РЕДАКТИРОВАТЬ: со страницы руководства:

-W
--dwarf
Displays  the  contents of the DWARF debug sections in the file, if
any are present.
Swegi
источник
6

Ответы, предлагающие использовать objdump --debuggingили readelf --debug-dump=...не работают в случае, если отладочная информация хранится в файле, отдельном от двоичного файла, т.е. двоичный файл содержит раздел отладочной ссылки . Возможно, это можно было бы назвать ошибкой вreadelf .

Следующий код должен обрабатывать это правильно:

# Test whether debug information is available for a given binary
has_debug_info() {
  readelf -S "$1" | grep -q " \(.debug_info\)\|\(.gnu_debuglink\) "
}

См. Раздел « Отдельные файлы отладки» в руководстве GDB для получения дополнительной информации.

подтверждать
источник