列出未使用的符号

Posted

技术标签:

【中文标题】列出未使用的符号【英文标题】:Listing Unused Symbols 【发布时间】:2010-12-15 10:43:59 【问题描述】:

我想从一个大型项目中删除死代码,并希望从未使用的符号开始。无论如何让链接器列出它已优化的未使用符号?我将 GNU 链接器 (LD) 与 GCC 一起使用。

如果做不到这一点,任何 Binutils(readelf 或 objdump)都可以执行相同的功能吗?

【问题讨论】:

Finding "dead code" in a large C++ legacy application 的可能重复项 这个问题是 Binutils 特有的 Is there a way to get gcc to warn about unused functions?的可能重复 【参考方案1】:

大多数编译器/链接器会优化未使用的符号。如果您在 *nix 系统上运行,您可以尝试对所有目标文件使用命令“nm”,对其进行过滤和排序,以生成由这些目标文件定义的所有导出函数的列表。

nm *.o | grep "^[0-9a-f]* T " | sed 's/^[0-9a-f]* T //' | sort -u > symbols_in.txt

我相信您可以对最终的二进制文件执行相同的操作。

然后,如果您对两组结果进行比较,您应该会得到所有未使用的导出函数的列表。

请注意,由于条件编译而被排除的代码可能会使用某些函数。例如。 #ifdef 开关表示在平台 A 上使用某某内置功能,而在另一个平台上使用您自己的函数版本,因为没有内置或标准库等效,或者它无法正常工作。

【讨论】:

我首先尝试了类似这种方法,但遇到了麻烦,因为在模块中声明的符号和 only 从该模块调用(而不是声明 static)看起来像他们重新使用。此外,默认情况下 gcc 无论如何都不会进行函数级链接,因此模块中未使用的函数与已使用的函数不会被消除。这个问题有一个更好的解决方案:Is there a way to get gcc to warn about unused functions?【参考方案2】:

GCC 在遇到未使用的函数、标签和函数参数时会生成编译器警告。编译器标志-Wunused -Wunused-parameter 将执行此操作。

我个人建议在开发时打开所有警告和额外警告。这些标志是-Wall -Wextra,这些标志暗示了死代码警告,以及我发现有用的许多其他警告。

【讨论】:

这只对不可重定位的符号有帮助。如果符号是可重定位的,我们必须等待链接器决定是否需要该符号,这样编译器将无法提供帮助。

以上是关于列出未使用的符号的主要内容,如果未能解决你的问题,请参考以下文章

强制链接到未使用的共享库

未加载符号,xamarin 项目上的 Visual Studio 或调试器有问题

像 nm -D 或 readelf -s 一样,使用 python ctypes 列出动态符号?

WinDBG 技巧:列出模块(DLL/EXE)里面所有的符号(symbol)

如何在不使用任何形式的查找表的情况下在 Swift for iOS 8 中列出(几乎)所有表情符号?

FluentAssertions Throw() 未列出使用