关于调试:删除C -STL / Boost调试符号(…或不创建它们)

关于调试:删除C -STL / Boost调试符号(…或不创建它们)

Remove C++-STL/Boost debug symbols (… or do not create them)

Linux / Gcc / LD-工具链。

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

  • 大型程序的链接变得很慢
  • 调试跳转到stl / boost代码中,这很烦人
  • 对于1.增量链接将是一个很大的改进,但是AFAIK ld不支持增量链接。在1999年dr.dobb的日记中有一种变通方法"伪增量链接"(不再在网络上,而是在archive.org中(想法是将所有内容都放在动态库中,而所有更新的目标文件都放在第二个库中)。首先加载),但这并不是真正的通用解决方案。

    对于2.,这里有一个脚本,但是a)对我不起作用(它没有删除符号),b)它很慢,因为它在管道的末尾起作用,但是它会更多有效地及早删除符号。

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


    GNU strip接受--strip-symbols =的正则表达式参数
    由于STL和boost符号所处的名称空间,它们被名称混为一谈。此刻我没有GCC binutils方便,但只是窥视用于名称空间的名称改写并为"来自名称空间X的符号构造正则表达式"并将其传递给--strip-symbols =


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

    否则,可以分开构建一个库,剥离该库,并与剥离后的版本链接。

    据我所知,在gcc中,只能从编译单元的某些部分获取调试符号,而不能进行编译和链接(以实现所需的链接时间加速)。


    此答案提供了一些使MSalters的答案有效以删除STL符号所需的细节。

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

    1
    > nm --debug-syms <objectfile>

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

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

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

    为了允许GNU Strip删除这些符号,我使用了:

    1
    2
    3
    4
    5
    6
    > 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命令来实现,如此处所示。

    希望对您有所帮助


    您可能要使用脱衣舞。
    删除--strip不需要的--strip调试libfoo.so

    为什么您不先构建而不进行调试?


    您可能不想从共享库中剥离调试符号,因为有时可能需要。

    如果您使用GDB或DDD进行调试,则可以从源路径中删除Boost源文件,从而无法跟踪功能。 (或者只是不追踪它们,追溯过去!)

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

    就像您链接到的脚本一样,您可以查询剥离程序(" man strip")以删除所有或某些符号。


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


    推荐阅读