我在gdb上看到许多教程,要求在编译c程序时使用-g选项。我无法理解-g选项实际上做了什么。
答案 0 :(得分:5)
它使编译器将调试信息添加到生成的二进制文件中。此信息允许调试器将代码中的指令与源代码文件和行号相关联。如果不可能的话,拥有调试符号会使某些类型的调试(如逐步调试代码)变得更加容易。
-g
选项实际上有一些可调参数,请查看手册。此外,如果您不优化代码,它最有用,因此使用-O0
或-Og
(在较新版本中) - 优化会破坏指令和源代码之间的连接。 (最重要的是,你必须不省略函数调用的帧指针,这是一种流行的优化,但基本上完全破坏了调用堆栈的能力。)
调试符号本身是用标准化语言编写的(我认为它是DWARF2),还有用于读取它的库。例如,程序甚至可以在运行时读取自己的调试符号。
稍后可以使用strip
命令从二进制文件中删除调试符号(以及函数名称等其他类型的符号)。但是,由于您通常会将调试符号与未优化的构建组合在一起,因此没有太多意义 - 相反,您将构建一个具有不同优化的发布二进制文件和,而不是从头开始的符号。
其他编译器(如MSVC)不在二进制本身中包含调试信息,而是将其存储在单独的文件和/或“符号服务器”中 - 因此,如果家庭用户的应用程序崩溃并且您获得核心转储,您可以从服务器中提取符号并获得可读的堆栈跟踪。海湾合作委员会可能会在未来添加这样的功能;我见过一些关于它的讨论。