gcc -g和不加-g以及strip和不strip的区别,对性能和内存使用有影响吗?

40
如果二进制文件大小不是问题,那么在性能关键环境中运行的二进制文件使用-g而不是strip会有什么缺点吗?我有很多磁盘空间,但二进制文件对CPU和内存要求较高。该二进制文件只加载一次,并且长时间运行。

编辑:

我想使用带有调试信息的二进制文件是为了在出现分段错误时生成有用的核心转储。


我认为问题的关键在于符号是否默认加载到内存中。如果是这样,这将会增加加载时间和内存消耗。有趣的问题,期待答案。+1 - 0xC0000022L
@unapersson:在我们的环境中进行这样的测试很困难,因为性能深度依赖于快速变化的外部因素。 - Johan
1个回答

33
ELF 加载器加载的是段(segments),而不是节(sections)。将节映射到段的操作是由用于构建可执行文件的链接脚本确定的。
默认的链接脚本没有将调试节映射到任何段中,因此这被省略了。
符号信息有两种类型:静态符号通过带外处理并且永远不会存储为节数据;动态符号表则由链接器生成,并添加到特殊的段中,与可执行文件一起加载,因为它需要访问动态链接器。strip 命令仅删除静态符号,这些符号在任何情况下都不会被引用到段中。
因此,您可以在整个过程中使用完整的调试信息,这不会影响 RAM 中可执行映像的大小,因为它未加载。这也意味着该信息不包含在核心转储中,因此在这里也没有任何好处。
objcopy 实用程序有一个特殊选项,只复制调试信息,因此您可以生成第二个 ELF 文件,其中包含此信息,并使用裁剪的二进制文件。在分析核心转储时,您可以将两个文件加载到调试器中。
objcopy --only-keep-debug myprogram myprogram.debug
strip myprogram

谢谢您这个详尽的解释!为了确认我理解得正确...使用-g选项构建的二进制文件将与剥离符号表的二进制文件(从相同的源代码构建)一样快地执行,并且在出现分段错误时,它们都会生成相同的核心转储文件? - Johan
没错。此外,剥离二进制文件会删除-g生成/保留的信息,再加上一些其他的内容,因此剥离后的结果应该与您是否使用-g编译无关。 - Simon Richter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接