【问题标题】:I have a release binary with no debug information build with gcc , have source code我有一个使用 gcc 构建的没有调试信息的发布二进制文件,有源代码
【发布时间】:2014-04-01 14:42:22
【问题描述】:

当我尝试使用调试模式构建源代码时,显示的堆栈完全不同,在发布的情况下,使用 gdb 的回溯中只显示了几个方法, 为什么会这样?这是因为在调试模式下有额外的方法,在调试和发布模式下怎么可能有两个方法具有相同的地址。 同样在这种情况下,我如何构建以获得具有完整堆栈跟踪的准确地址信息。任何帮助将不胜感激,因为我是在 Linux 和 Windows 上调试的新手,使用 pdb 文件似乎更容易。

【问题讨论】:

    标签: c++ debugging gdb


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      任何帮助将不胜感激,因为我是在 Linux 上调试的新手, Windows 使用 pdb 文件似乎要容易得多。

      Windows 二进制文件调试有什么显着差异吗?

      【讨论】:

        【解决方案3】:

        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 等调试器使用。

        【讨论】:

        • +1 @Manu343726,是的。这与这部分完全相关:“当我尝试使用调试模式构建源代码时,显示的堆栈完全不同,并且在发布的情况下,使用 gdb 的回溯中只显示了几个方法,为什么会发生这种情况?”
        • @rerx 编写g++ -g 文档不是该问题的答案......答案是缺乏调试符号和优化(内联,在较少函数的情况下)执行编译器处于发布模式。
        • @Manu,像内联这样的真正优化也将发挥作用。但是省略-g 就是:不提供调试符号。
        猜你喜欢
        • 1970-01-01
        • 2017-05-28
        • 2014-03-12
        • 2012-06-27
        • 2019-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多