【问题标题】:Debug symbols stability调试符号稳定性
【发布时间】:2021-11-25 18:37:52
【问题描述】:

我正在编译一个带有-g 选项的应用程序:

gcc -g -o main1 main.c

然后我从中剥离调试对象:

objcopy --strip-debug main1

假设我的main1 应用程序将崩溃,我想使用核心转储coredump1 来调试问题。

我可以再重新编译一次源代码吗

gcc -g -o main2 main.c

并提取调试符号

objcopy --only-keep-debug main2 main2.debug

并使用main2.debug调试coredump1?

我可以相信调试符号总是对齐的吗?它是由语言标准或编译器要求保证的吗?

如果我的源代码包含基于__DATE__ 或__TIME__ 等宏的字符串,调试符号是否匹配?

如果我启用代码优化,它会起作用吗?

【问题讨论】:

  • 即使会,也不要将您的业务/声誉/收入/...赌在上面。每次分发二进制文件时,请保留匹配的调试符号的副本。您可以稍后通过程序中嵌入的构建 ID 将它们关联起来。
  • 如果 main2 的 main.c 与 main1 的 main.c 不同,则不能保证任何内容都对齐。因此,您需要保留 main1 的调试副本,或者有一种真实的方法来从具有相同限定符的相同源复制 main1 构建。至于__DATE__ 和__TIME__,尽管日期和时间是真实的,但它们应该生成相同格式的字符串。因此,它们不应影响调试信息。
  • 如果您正在发布程序 - 那么您应该保留一份发布的可执行文件的副本,其中包含匹配的调试符号(发布版本),并在源代码控制系统中标记/标记源代码。标准或工具链文档中的任何内容都不能保证您始终可以完全重建。人们跳过箍让自动构建系统产生相同的结果(时间戳是问题的来源之一)。
  • @Serge 也许我表达得不够清楚,但假设在两个编译中我都使用相同的main.c 文件。所以这个问题可以用以下形式重新表述——我可以相信在同一源文件的每次编译中,它总是会生成相同的调试符号。根据 Botje 和 Richard Critten 的回答,我得出结论认为这样的假设是不正确的。
  • 只要你的时间戳产生相同长度的字符串并且不影响声明的静态变量的大小,只要你使用相同版本的 gcc、相同的限定符和相同版本的操作系统,你就有获得相同编译/调试结果的好机会。

标签: c++ c debugging standards coredump


【解决方案1】:

调试符号是否匹配...
如果我启用代码优化,它会起作用吗?

正如其他人评论的那样,您不应该依赖这一点,而是始终使用-g 构建并在发布“最终产品”之前将调试符号分开。

也就是说,实际上这 适用于 GCC1 有或没有优化,但对 Clang/LLVM 根本不起作用(这给了你一个实际的理由不依赖于此)。


1 或者至少几年前我上次尝试对几个重​​要的二进制文件进行此操作时确实如此。

请注意,维护此属性需要编译器开发人员主动努力,因此可以在引入、注意和修复违规行为时破坏。

【讨论】:

    猜你喜欢
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 2017-10-20
    • 1970-01-01
    相关资源
    最近更新 更多