【问题标题】:Are there any downsides to compiling with -g flag?使用 -g 标志编译有什么缺点吗?
【发布时间】:2021-07-31 13:27:45
【问题描述】:

GDB 文档告诉我,为了进行调试编译,我需要让我的编译器生成调试符号。这是通过指定一个“-g”标志来完成的。

此外,GDB 文档建议我始终使用“-g”标志进行编译。这听起来不错,我想这样做。

但首先,我想了解一下缺点。在生产代码中进行编译调试是否有任何惩罚?

我最感兴趣的是:

  1. GCC 作为编译器的选择
  2. Red hat Linux 作为目标操作系统
  3. C 和 C++ 语言

(尽管也欢迎提供有关其他环境的信息)

非常感谢!

【问题讨论】:

    标签: c++ c debugging gcc gdb


    【解决方案1】:

    如果您使用-g最近GCCClang 可以与-O2 等优化标志一起使用):

    • 编译时间较慢(链接会占用更多内存)
    • 可执行文件是一个更大的文件(请参阅elf(5) 并使用readelf(1)...)
    • 可执行文件包含有关您的源代码的大量信息。
    • 您可以轻松使用GDB
    • 一些有趣的库,例如 Ian Taylor 的 libbacktrace,需要 DWARF 信息(例如 -g

    如果您不使用-g,则使用 GDB 调试器会更困难(但可能)。

    因此,如果您将二进制可执行文件传输给不了解您的源代码是如何编写的合作伙伴,您需要避免-g

    另请参阅strip(1)strace(1) 命令。

    请注意,使用-g 标志作为调试信息对OcamlRust 也有效

    PS。最近的 GCC(例如 2021 年的 GCC 10GCC 11)接受许多 debugger flags。使用-g3,您的可执行文件携带比-g-g1 更多的调试信息(例如C++ 宏及其扩展的描述)。当然,编译时间增加了,可执行文件的大小也增加了。原则上,你的GCC plugin(可能是2021年的Bismon,或者Linux源代码中的kernel)可以添加更多的调试信息。实际上,除非您可以改进调试器,否则您不会这样做。但是,GCC 插件(或某些 #pragmas)可以删除一些调试信息(例如,删除选定组函数的调试信息)。

    【讨论】:

      【解决方案2】:

      通常,添加调试信息会增加二进制文件的大小(或为调试信息创建额外的文件)。现在这通常不是问题,除非您通过慢速网络分发它。当然,如果其他人想这样做,这些调试信息可能会帮助其他人分析您的代码。通常情况下,-g 标志与-O0(默认)一起使用,它会禁用编译器优化并生成尽可能接近源代码的代码,以便调试更容易。虽然您可以将调试信息与启用的优化一起使用,但这确实很棘手,因为变量可能不存在,或者指令序列可能与源代码中的不同。这通常仅在需要分析仅在启用优化后发生的错误时才执行。当然,-O0 的缺点是性能较差。

      因此得出结论:通常在开发过程中使用-g -O0,而对于分发或生产代码,只需使用-O3

      【讨论】:

        猜你喜欢
        • 2012-01-15
        • 1970-01-01
        • 1970-01-01
        • 2017-01-05
        • 2014-02-04
        • 2012-05-07
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        相关资源
        最近更新 更多