【发布时间】: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