使用核心转储在Linux中进行调试

时间:2010-02-15 07:52:05

标签: c++ linux debugging gdb

使用GDB调试核心转储时的“最佳实践”是什么?

目前,我遇到了一个问题:

  • 我的应用程序的发行版本是在没有'-g'编译器标志的情况下编译的。
  • 我的应用程序的调试版本(使用'-g'编译)已存档(连同源代码和发布二进制文件的副本)。

最近,当用户给我核心转储时,我尝试使用

进行调试
gdb --core=./core.pid ./my_app_debug-bin

核心由my_app_release-bin创建。核心文件和二进制文件之间似乎存在某种不匹配。

另一方面,如果我尝试

gdb --core=./core.pid ./my_app_release-bin

核心匹配,但我无法获得源代码行号(虽然我得到了函数名称)。

这是实践的吗?因为我觉得我在这里错过了一些东西。

3 个答案:

答案 0 :(得分:16)

听起来你的发布和调试版本之间存在其他差异,然后只是缺少/存在-g标志。假设是这种情况,你现在无法做任何事情,但你可以调整你的构建来更好地处理这个问题:

这是我们在工作场所所做的事情。

  1. 构建发布版本时包含-g标志。
  2. 归档该版本。
  3. 在将二进制文件发送给客户之前运行strip --strip-unneeded
  4. 现在,当我们遇到崩溃时,我们可以使用带符号的存档版本来进行调试。

    需要注意的一点是,如果您的发布版本包含优化,即使使用符号也可能难以进行调试。例如,优化器可以对您的代码重新排序,因此即使调试器会说您在第N行崩溃,也不能假设代码实际执行了N-1行。

答案 1 :(得分:5)

您需要做一些额外的工作来创建带有剥离调试信息的二进制文件,然后您可以从核心调试。我能找到的最佳描述是here

答案 2 :(得分:1)

不,你什么都不错过。调试和发布只是不同的二进制文件,因此发布的核心文件与调试二进制文件不匹配。您必须查看机器代码才能从发布核心转储中获取内容。

您可能需要询问您的用户崩溃是如何发生的,并收集其他日志信息或您应用的任何内容。