我有一个发布二进制文件没有使用gcc构建调试信息,有源代码

时间:2014-03-31 16:45:28

标签: c++ debugging gdb

当我尝试使用调试模式构建源时,显示的堆栈完全不同,并且在发布的情况下,使用gdb的回溯中只显示了一些方法, 为什么会这样?这是因为在调试模式下有额外的方法,如何让两个方法在调试和释放模式下具有相同的地址。 同样在这种情况下,我如何构建以获得具有完整堆栈跟踪的准确地址信息。任何帮助都会受到赞赏,因为我不熟悉Linux上的调试,使用pdb文件看起来要容易得多。

3 个答案:

答案 0 :(得分:1)

正如@ rockoder的回答中所讨论的那样,除了在优化构建中缺少调试符号(将包含在-g中)之外,由于内联,整个函数调用可能不再存在。

答案 1 :(得分:1)

  

当我尝试使用调试模式构建源时,显示的堆栈是   完全不同,如果发布,只有几种方法   在使用gdb的回溯中显示,为什么会发生这种情况?这是   因为在调试模式下有额外的方法吗?

这可能仅仅是由于编译器优化。你所谓的发布版本可能是在启用编译器速度优化和禁用调试符号的情况下构建的。速度优化包括代码内联,它只是复制函数代码而不是调用它,因此函数在调用堆栈中不可见。 如果代码是用一些适当的预处理器检查编写的,那么也可能有一些额外/不同的方法。

  

如何让两个方法在调试和发布中具有相同的地址   模式。

取决于您的调试和发布模式。如果它们使用相同的编译器优化并且仅在调试信息方面不同​​,则方法将具有相同的地址。如果你没有优化调试版本(GCC上的-O0),那么方法会更大,因为做了很多不必要的工作,例如在每次操作之前从内存读取变量并在之后写回。由于每种方法可能都较小,因此函数将具有不同的地址,因为它们通常是一个接一个地打包。

  

同样在那种情况下我如何建立以获得准确的地址   具有完整堆栈跟踪的信息。

启用调试信息。在GCC上将是-g3(或-g或类似)。这为代码地址添加了足够的信息< - >源代码行查询(来自调试器或崩溃堆栈转储)。

  

任何帮助都会受到赞赏,因为我刚接触Linux上的调试,   使用pdb文件,Windows看起来要容易得多。

Windows二进制文件调试是否存在显着差异?

答案 2 :(得分:0)

g ++ / gcc有许多用于调试程序的选项,但最常见的选项是-g。请参阅link。讨论的第一个选项是-g

一些其他信息here

示例:

编译没有-g的代码:

g++ broken.cpp -o broken_release

使用-g编译代码:

g++ -g broken.cpp -o broken_debug

现在点击ls -l并注意文件broken_releasebroken_debug之间的大小不同。 broken_debug的大小应该大于broken_release的大小。那是因为它包含可以由gdb等调试器使用的调试信息。