编译产生调试信息
GDB 调试程序需要在源文件编译阶段产生调试信息。调试信息存储在目标文件中,主要包括行号、变量的类型和作用域、函数名字、函数参数和函数的作用域等源文件的特性。
编译源文件的时候,使用-g
选项可以产生调试信息,较早以前的 C 语言编译器也允许使用-gg
选项来产生调试信息,但是现在版本的 GDB 不再支持这种格式产生的调试信息,所以不建议使用-gg
选项。
在 Linux 中 GCC 编译器使用-g
选项编译文件时,编译器还会做出以下额外的操作:
- 创建符号表,符号表包含了程序中使用的变量名称的列表。
- 关闭所有的优化机制,以便执行程序过程中样按照原来的C代码进行。
编译器会把优化机制自动的关闭,是不是意味着编译程序不能使用-O
选项?其实这个与使用的编译器有关。有的编译器不支持-g
和-O
参数选项同时处理,所以得不到带有调试信息并且优化过的可执行程序。GCC 编译器是支持这两个参数同时使用,所以 GDB 可以调试经过编译优化后并且带有调试信息的程序。
注意:如果使用 GCC 编译时使用了优化选项-O
,那么优化器会重新编排已经编写好的代码。调试器显示的是真正编译生成的代码,在执行路径和编写的源代码不一致是常见的。例如,源文件中定义了一个变量,但从来这个变量没有使用过。优化编译后使用 GDB 调试会发现没有这个变量,这就是优化器把变量给去除了。
GDB 启动程序
产生调试信息以后,就可以使用 GDB 来启动程序。使用 GDB 启动程序一般有以下三种方式:
1) 直接启动可执行程序
直接启动可执行程序的方法为:
gdb fileName
fileName 为可执行程序的名字。下面是一个简单的例子:
gdb test
test 就是我么生成的可执行文件的名字,这是最常见最简单的启动方式。启动时指定对象,进入 GDB 中可以直接对文件进行调试。
2) 启动 core 文件
启动可执行文件产生的 core 文件的方法为:
gdb fileName file_core
fileName 是可执行文件的名字,file_core 是 fileName 运行产生的 core 文件。下面是一个简单的例子:
gdb test test_core
test_core 为 test 运行时产生的 core 文件。当可执行程序运行时产生段错误,系统就会产生 core 文件(开启系统的 core dump 功能),gdb 对产生的 core 文件进行分析,可以还原系统发生段错误时刻的堆栈情况,这对于我们发现程序bug很有帮助。
3) 启动进程
启动进程的方式:
gdb fileName PID
fileName 是可执行文件的名字,PID 进程号。下面是一个简单的例子:
gdb test 1234
GDB 将调试程序 test 附加到进程 1234 上进行调试。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/23642.html