如何判断一个库是不是是用 -g 编译的?

Posted

技术标签:

【中文标题】如何判断一个库是不是是用 -g 编译的?【英文标题】:How can I tell if a library was compiled with -g?如何判断一个库是否是用 -g 编译的? 【发布时间】:2011-01-01 06:17:23 【问题描述】:

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

【问题讨论】:

【参考方案1】:

如果您在 Linux 上运行,请使用 objdump --debugging。库中的每个目标文件都应该有一个条目。对于没有调试符号的目标文件,您会看到如下内容:

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

voidincr.o:     file format elf64-x86-64

如果有调试符号,输出会更详细。

【讨论】:

还有obdjump -W libreadelf -w lib。后者更易于配置 - 请参阅 readelf(1) 手册页。 对于任何二进制文件(包括那些使用 -g 编译的),objdump 都会给我“无法识别调试信息”的响应,除非我使用 -gstabs 编译它。这似乎是一个公认的错误。 Dan,你在哪个平台上试过这个? Employed Russian: from man objdump(1), --debugging 标志“试图解析文件中存储的 STABS 和 IEEE 调试格式信息,并使用类似 C 的语法将其打印出来。如果两者都没有这些格式被发现此选项依赖于 -W 选项来打印文件中的任何 DWARF 信息。" objdump -g 给我一个简单的 test.o 什么都没有,无论有没有g 都编译,这使它实际上毫无用处。 Ubuntu 12.04、gcc 4.6.3、GNU objdump 2.22。 nm -a 似乎更有用。【参考方案2】:

建议的命令

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

这将打印出由源文件名、行号和地址组成的一组行如果此类调试信息包含在库中,否则它将打印nothing

您可以传递--debug-dump 选项而不是decodedline 所需的任何值。

【讨论】:

完美运行。我用第一个 CMAKE_BUILD_TYPE RELEASE 在我的可执行文件上尝试了这个命令,命令返回空。然后我用 CMAKE_BUILD_TYPE DEBUG 试了下,输出还是蛮多的。【参考方案3】:

帮助的是:

gdb mylib.so

当找不到调试符号时打印:

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

或者找到时:

Reading symbols from mylib.so...done.

之前的答案都没有给我带来有意义的结果:没有调试符号的库提供了大量的输出,等等。

【讨论】:

谢谢!这对我有用,在带有 cmake 的 android 中使用 clang 编译器:) 非常适合快速检查!也适用于 *.o 目标文件。【参考方案4】:

nm -a <lib> 将打印库中的所有符号,包括调试符号。

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

【讨论】:

@Employed 俄语 你能详细说明一下吗?为什么你认为这是一个错误的工具?它可以完成这项工作,并且在 Linux 上也可以。 即使对于基于内核 2.6.35 的嵌入式 linux,xxx-objdump、xxx-nm 也能正常工作。 nm -a 有别名 nm --debug-syms 这是不言自明的:-)。 只需键入diff <(nm <lib>) <(nm -a <lib>) 即可轻松获取差异【参考方案5】:

在 OSX 上,您可以使用 dsymutil -sdwarfdump

使用dsymutil -s <lib_file> | more,您将在带有调试符号的文件中看到源文件路径,否则只能看到函数名。

【讨论】:

您能否详细说明在dsymutil -s 的输出中要查找的内容?输出的存在是否意味着它是用调试符号构建的,还是应该被grep?【参考方案6】:

您可以为此使用objdump。

编辑:从手册页:

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

【讨论】:

【参考方案7】:

建议使用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 手册中的Separate Debug Files。

【讨论】:

所以,readelf -S example | grep debug 会更好。使用readelf --debug-dump=links example | grep link(GNU readelf 版本 2.31.1-13.fc29)查找链接文件

以上是关于如何判断一个库是不是是用 -g 编译的?的主要内容,如果未能解决你的问题,请参考以下文章

如何在编译时判断项目是程序还是库?

如何将源文件编译成库文件

如何交叉编译 动态库

如何判断应用程序是不是为 MFC 程序?

linux 下如何将动态链接库.so进行反编译后,换编译器重新编译?

如何识别mingw编译库是不是成功