5

Linux/Gcc/LD - 工具链。

我想从库和可执行文件中删除 STL/Boost 调试符号,原因有两个:

  1. 大型程序的链接速度很慢
  2. 调试跳转到stl/boost代码,烦人

对于 1. 增量链接将是一个很大的改进,但 AFAIK ld 不支持增量链接。在 1999 年 dobb 博士的日记中有一种解决方法“伪增量链接”(不再在网络中,而是在archive.org中(想法是将所有内容放在动态库中,并将所有更新的目标文件放在第二个库中)首先加载)但这并不是一个真正的通用解决方案。

对于2.这里有一个脚本但是a)它对我不起作用(它没有删除符号),b)它非常慢,因为它在管道末端工作,而删除它会更有效前面的符号。

显然,其他调试符号应该保留在原处。

4

6 回答 6

3

GNU strip 接受 --strip-symbols= 的正则表达式参数 STL 和 boost 符号由于它们所在的命名空间而被名称修改。我现在没有方便的 GCC binutils,但只是看看使用的名称修改用于命名空间并为“来自命名空间 X 的符号”构造正则表达式并将其传递给 --strip-symbols=

于 2008-09-17T10:03:31.357 回答
2

据我所知,在 gcc 中没有真正的选择可以做你想做的事。主要问题是您要删除调试符号的所有代码都在标头中定义。

否则,可以单独构建一个库,剥离它,并与剥离的版本链接。

但据我所知,在 gcc 中仅从编译单元的某些部分获取调试符号,同时构建和链接(为了您所需的链接时间加速)是不可能的。

于 2008-09-16T18:52:55.447 回答
1

您可能不想从共享库中删除调试符号,因为您可能在某些时候需要这样做。

如果您使用 GDB 或 DDD 进行调试,您可能能够从源路径中删除 Boost 源文件,这样它就无法追踪到函数。(或者只是不追查他们,追查!)

您可以删除使用调试符号编译程序的选项,这将加快链接时间。

就像您链接到的脚本一样,您可以参考 strip 程序(“man strip”)来删除所有或某些符号。

于 2008-09-16T16:12:09.467 回答
1

您可能想使用条带。剥离 --strip-unneeded --strip-debug libfoo.so

你为什么不一开始就在不调试的情况下构建呢?

于 2008-09-16T16:13:54.220 回答
1

这个答案提供了一些细节,我需要让 MSalters 的答案适用于删除 STL 符号。

STL 符号名称被破坏。诀窍是找到一个覆盖这些名称的正则表达式。我用 GNU 的 Binutils 查找了这些符号:

> nm --debug-syms <objectfile>

我基本上搜索了 STL 函数,比如resize. 如果这很困难,则使用以下命令时输出变得可读:

> nm --debug-syms --demangle <objectfile>

查找包含 STL 函数调用的行号,然后使用提供的第一个命令在同一行号上查找它的错位名称。这让我看到所有 STL 符号名称都以_ZNSt[0-9]+_ZSt[0-9]+等开头。

为了让 GNU Strip 删除我使用的这些符号:

> strip --wildcard              \
    --strip-symbol='_ZNKSt*'    \
    --strip-symbol='_ZNSt*'     \
    --strip-symbol='_ZSt*'      \
    --strip-symbol='_ZNSa*'     \
    <objectfile>

我直接在编译/链接的二进制文件上使用了这些命令。我通过比较nm删除前后的输出来验证这些符号的删除(我将输出写入文件并使用vimdiff)。该--wildcard选项允许使用正则表达式。虽然我希望[0-9]*表示 0 到无限数量的数字,但这里它实际上意味着 1 个数字后跟无限数量的任何东西(直到行尾)。

如果您不想进入 STL 代码,这可以通过 gdb 的skip file命令来实现,就像在此处完成的那样。

希望能帮助到你

于 2017-03-08T11:05:52.657 回答
-1

您使用的是哪个编译器?例如,如果我正确理解您的问题,这在 MS Visual Studio 中是一件小事。

于 2008-09-16T15:27:41.587 回答