列出未使用的符号
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)