-g选项在gcc中做什么

我看到很多关于gdb的教程要求在编译c程序时使用-g选项。 我无法理解-g选项实际上做了什么。

它使编译器将调试信息添加到生成的二进制文件中。 此信息允许调试器将代码中的指令与源代码文件和行号相关联。 调试符号使得某些类型的调试(如逐步调试代码)变得更加容易,如果根本不可能的话。

-g选项实际上有一些可调参数,请查看手册。 此外,如果您不优化代码,它是最有用的,因此使用-O0-Og (在较新版本中) – 优化会破坏指令和源代码之间的连接。 (最重要的是,你不必省略函数调用的帧指针,这是一种流行的优化,但基本上完全破坏了调用堆栈的能力。)

调试符号本身是用标准化语言编写的(我认为它是DWARF2),还有用于读取它的库。 例如,程序甚至可以在运行时读取自己的调试符号。

稍后可以使用strip命令从二进制文件中删除调试符号(以及函数名称等其他类型的符号)。 但是,由于您通常将调试符号与未优化的构建组合在一起,因此没有太多意义 – 相反,您将构建一个具有不同优化从一开始就没有符号的发布二进制文件。

其他编译器(如MSVC)不在二进制本身中包含调试信息,而是将其存储在单独的文件和/或“符号服务器”中 – 因此,如果家庭用户的应用程序崩溃并且您获得核心转储,则可以从服务器中提取符号并获得可读的堆栈跟踪。 GCC可能会在未来添加这样的function; 我见过一些关于它的讨论。