GDB是什么
GDB是由GNU软件系统社区提供的调试工具,同GCC配套组成了一套完整的开发环境
GDB可以帮助完成下面四个功能:
- 启动程序,可以按照自定义要求运行程序
- 可以让调试的程序在指定断点位置停住
- 当程序停住时可以检查程序中发生的事情
- 可以改变程序,将一个bug产生的影响修正从而测试其他bug
预先准备
如果为了调试而编译我们通常会
- 关掉优化选项(-o)
- 打开调试选项(-g)
- -Wall尽量全开
gcc -g -Wall program.c -o program
-g选项的作用是在可执行文件中加入源代码信息,但是不把整个源文件嵌入进去,所以调试时要保证gdb能找到源文件
基本命令
启动 gdb 可执行程序
退出 quit
给程序设置参数 set args 10 20
获取设置参数 show args
使用帮助 help
查看当前文件代码
list/l
list/l 行号
list/l 函数名
查看非当前文件代码
list/l 文件名:行号
list/l 文件名:函数
设置显示的行数
show list/listszie
sei list/listszie 行数
例子
使用事先写好的main.c,add.c,sub.c和makefile文件来做样例 不带-g的Makefile
src=$(wildcard ./*.cpp)
objs=$(patsubst %.cpp, %.o, $(src))
target=A
$(target):$(objs)
$(CXX) $(objs) -o $(target)
%.o:%.cpp
$(CXX) -c $< -o $@
clean:
rm $(objs) -f
带-g的Makefile
src=$(wildcard ./*.cpp)
objs=$(patsubst %.cpp, %.o, $(src))
target=A2
$(target):$(objs)
$(CXX) $(objs) -o $(target) -g
%.o:%.cpp
$(CXX) -c $< -o $@ -g
clean:
rm $(objs) -f
对比生成的A和A2
可以发现,A2比A更大一些,因为里面包含了源代码的信息(注意不是直接嵌入)
如果生成编译的时候没有加-g参数,会报错:无符号列表,原因是没找到源代码相关信息
获取帮助
使用gdb help进入帮助界面
使用help all可以查询所有指令
使用help 指令名可以查询对应的命令
查看文件代码
使用list查看文件代码(每次有行数限制)
如果一次list显示不完全可以再次使用list或者按回车(执行上一个指令),来显示接下来的部分
查看特定函数 list/l 后面跟上函数名即可
查看其他文件
原本Makefile编译的调不了,应该是-g没有直接把.c文件信息加进去,加了.o文件的信息
使用下面截图里的指令重新编译后可以查看其他文件
l 文件名:函数名
l 文件名:行号
查看和设置行数
打断点
设置断点
b/break 行号 b/break 函数 b/break 文件名:行号 b/break 文件名:函数
查看断点
i/info b/break
删除断点
d/del/delete 断电编号
设置断点无效
dis/disable 断点编号
设置断点生效
ena/enable 断点编号
设置条件断点(一般用在循环的位置)
b/break 行数 if i==5
运行GDB程序
运行GDB程序
start 程序停在第一行 run 遇到断点才停
继续运行,到下一个断点停
c/continue
向下执行一行代码(不会进入函数体)
n/next
变量操作
p/print 变量名(打印变量值) ptype 变量名 (打印变量类型)
向下单步调试(遇到函数进入函数体)
s/step finish (跳出函数体)
自动变量操作
display num(自动打印指定变量的值) i/info display undisplay 编号
其他操作
set var 变量名=变量值 until (跳出循环,循环内部不能有断点,当前循环代码要执行完)
gdb追踪父/子进程
follow-fork-mode [parent(默认)|child] #默认追踪父进程
show ~ #查看追踪模式
set ~ #设置追踪模式
是否脱离GDB调试
detach-on-fork [on(默认)|off] #默认gdb追踪的进程以外的进程为继续运行,若off则为被挂起
set ~ #设置是否被挂起
show ~ #查看是否被挂起
inferiors
info ~ #查看进程消息
~ [inferiorsID] #切换到指定进程
det/detach ~ [inferiorsID] #使指定的进程脱离gdb调试
多线程调试
多进程调试时,会需要用到<pthread.h>,需要连接pthread线程库,编译时加 -lpthread【例如 gcc -c thread.c -o thread -lpthread -g】
info threads #查询线程信息
thread [threadID] #切换线程
thread apply [threadid] [all] args #对线程列表执行命令
set print thread-events #控制线程开始和结束时的打印信息
show print thread-events #显示线程打印信息的开关状态