我如何判断一个库是否使用了-g进行编译?

125

我在x86 Linux上有一些编译好的库,我希望能快速确定它们是否使用了调试符号。

8个回答

108
建议使用的命令为:
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-dump 选项,而不是 decodedline


1
完美运行。我尝试在我的可执行文件上使用了第一个 CMAKE_BUILD_TYPE RELEASE 命令,命令返回为空。然后我尝试了 CMAKE_BUILD_TYPE DEBUG,输出了很多内容。 - infoclogged

104

如果你正在运行Linux系统,使用objdump --debugging命令。每个库中的目标文件应该都有一个条目。对于没有调试符号的目标文件,你会看到类似以下内容:

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

voidincr.o:     file format elf64-x86-64

如果存在调试符号,输出信息会更加冗长。


6
还有obdjump -W libreadelf -w lib 两种命令。后者更加可配置,详见readelf(1)手册页。 - przemoc
4
除非我使用-gstabs选项进行编译,否则对于任何二进制文件(包括已使用-g编译的文件),objdump都会显示“没有识别到调试信息”的消息。这似乎是一个已知的错误。 - Dan Hook
从man objdump(1)中得知,--debugging标志“尝试解析存储在文件中的STABS和IEEE调试格式信息,并使用类似于C的语法将其打印出来。如果没有找到这些格式,则此选项会回退到-W选项以打印文件中的任何DWARF信息。” - Matt McClellan
5
使用objdump -g命令对编译了g和未编译g的简单测试文件test.o进行反汇编,结果为空,因此该命令无效。在Ubuntu 12.04系统、gcc 4.6.3编译器和GNU objdump 2.22版本下,使用nm -a命令似乎更加有用。 - jw013
在Linux共享库(*.so)上进行测试时,如果没有调试符号,会产生大量输出。使用nm -a命令看起来更可靠。 - pevik
显示剩余2条评论

52

有帮助的是:

gdb mylib.so

当未找到调试符号时,它会打印信息:

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

或者当找到时:

Reading symbols from mylib.so...done.

之前的回答都对我没有帮助,没有调试符号的库输出了很多内容等等。


谢谢!这对我有用,在Android上使用clang编译器和cmake :) - Pär Nils Amsen
非常适合快速检查!还可用于*.o目标文件。 - Stephane Rolland

35

nm -a <lib> 命令会打印出库文件中的所有符号,包括调试符号。

因此,您可以将 nm <lib>nm -a <lib> 的输出进行比较,如果它们不同,则表示您的库文件中包含一些调试符号。


3
请问您能详细说明一下吗?为什么您认为这是一个错误的工具?它可以完成任务,并且也可以在Linux上运行。 - qrdl
即使是基于2.6.35内核的嵌入式Linux,xxx-objdump和xxx-nm也能正常工作。 - agfe2
1
nm -a 有别名 nm --debug-syms,这个别名已经很明显了 :-)。 - pevik
4
只需键入 diff <(nm <lib>) <(nm -a <lib>) 即可轻松获取差异。 - Aᴄʜᴇʀᴏɴғᴀɪʟ

19
在OSX上,您可以使用dsymutil -sdwarfdump
使用dsymutil -s <lib_file> | more,您将在具有调试符号的文件中看到源文件路径,但仅查看函数名称的其他文件。

15
你能否详细说明一下,比如说dsymutil -s的输出中应该看到哪些内容?输出的存在是否表示已经启用了调试符号,或者需要使用grep命令来查找? - Mitch

12

您可以使用objdump进行此操作。

编辑:来自手册页面:

-W
--dwarf
Displays  the  contents of the DWARF debug sections in the file, if
any are present.

1
无法在macOS的LLDB objdump中工作:错误:未知参数'--dwarf' - user3064538

8

建议使用objdump --debuggingreadelf --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手册中关于分离调试文件的更多信息。


因此,readelf -S example | grep debug 更好。使用 readelf --debug-dump=links example | grep link 可以找到链接文件(GNU readelf 版本为 2.31.1-13.fc29)。 - Nick Dong

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接