前言
笔者近几年使用 Python 语言来做深度学习、计算机视觉领域相关科研与工作,对于调试程序,使用较多的工具除了 JetBrains 家的各个 IDE 以外,就是使用 Python 自带的 pdb 模块来调试 Python 程序,命令行界面调试代码既灵活,而且速度也快,非常好用。最近,因为项目原因接触 c/c++ 代码更多一些,通过本篇博客对 GDB 学习并且记录相关常用命令。
GDB是一个由GNU开源组织发布的、UNIX / LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。 对于一名Linux下工作的c/c++程序员,gdb是必不可少的工具,另外,GDB可以调试Ada、C、 C++、 Asm、 Minimal、 D、 Fortran、 Objective-c、 Go、 Java、 Pascal等语言。标准的 GDB 是纯命令行式的,但也有一些基于它的图形化工具(比如 DDD、Data Display Debugger),但用好 GDB 命令行调试,还是我们的一项基本素质。
本篇文章将简单地介绍 GDB 常见用法,更多内容通过本博客下面的参考资料学习。
GDB 使用流程
启动 GDB 调试
学习 GDB 调试测试的代码如下:
|
|
通过下面命令编译 C++ 代码,注意需要使用 -g 参数,在编译生成的目标文件中加入源码信息,并启动 GDB 调试代码:
|
|
查看源码
list
(简写 l
): 查看源程序代码,默认显示10行,按回车键或继续输入l查看下10行。
|
|
运行程序
run
(简写 r
) :运行程序直到遇到 结束或者遇到断点等待下一个命令:
|
|
设置断点
break
(简写 b
) :命令格式 b 行号
,在某行设置断点:
info breakpoints
(简写 i b
) :显示断点信息。
- Num: 断点编号
- Type:类型,breakpoint 或者 watchpoint
- Disp:断点执行一次之后是否有效 kep:有效 dis:无效
- Enb: 当前断点是否有效 y:有效 n:无效
- Address:内存地址
- What:位置
|
|
条件断点:
|
|
具体参考:GDB条件断点详解
单步执行
首先需要输入 run
启动程序,运行到第一个断点处,然后可以选择 step
单步调试(如果有函数调用则进入函数),next
单步跟踪程序(遇到函数调用,直接调用函数,不会进入函数体内),continue
继续运行到下一个断点处。
|
|
运行程序相关命令如下:
run
:简记为r
,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令;continue
(简写c
):继续执行,到下一个断点处(或运行结束);next
:(简写n
),单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同step 的主要区别是,step
遇到用户自定义的函数,将步进到函数中去运行,而 next 则直接调用函数,不会进入到函数体内。step
:(简写s
):单步调试如果有函数调用,则进入函数;与命令n
不同,n
是不进入调用的函数的;until
:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体;until 行号
: 运行至某行,不仅仅用来跳出循环;finish
: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。call 函数(参数)
:调用程序中可见的函数,并传递“参数”,如:call gdb_test(55)
查看变量
print
:简记p
,打印变量或表达式的值;whatis
:查询变量或函数的类型;pt
:跟whatis
作用类似,可能是print type
的简写;display
:在单步调试的时候很有用,使用display
命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值;info dispaly
,查看当前被设置的变量,然后可以用undisplay num(变量对应的编号)
取消设置;
|
|
退出 GDB
使用 quit
(简记 q
)命令退出即可。
GDB 常用命令
下面列出最常用的GDB命令:
pt
:查看变量的真实类型,不受 typedef 的影响;bt
:显示当前调用堆栈;up/down
:在函数调用栈里上下移动。或者使用frame 函数帧号跳转;fin
:直接运行到函数结束;i b
:查看所有的断点信息;delete
:删除所有断点;delete breakpoint_list
:删除某个序号处断点;i locals
:查看当前堆栈页的所有变量;wh
:启动“可视化调试”。这个是我最喜欢的命令,可以把屏幕分成上下两个窗口,上面显示源码,下面是 GDB 命令输出,不必再用“l”频繁地列出源码了,能够大大提高调试的效率;ctrl x + a
:退出或进入可视化模式;layout regs
:显示源代码/汇编和寄存器窗口;layout split
:显示源代码和汇编窗口;p *array@10
:查看数组内容,这里10表示查看数组的大小;ptype
:查看变量的类型,这里打印出变量的结构定义;set args config.txt
:指定运行时的参数;
GDB 多线程命令
info thread
:查看被调试的线程;thread apply all bt
:打印所有线程堆栈信息;thread <ID>
:切换调试的线程为指定ID的线程;break file.c:100 thread all
:在file.c文件第100行处为所有经过这里的线程设置断点;set scheduler-locking off|on|step
:在调试多线程程序时,默认除了被调试的线程在执行外,其他线程也都在运行,我们可以通过命令来控制这一切:off表示不锁定任何线程on表示只有当前调试的线程会继续运行,step表示在但不执行时只有当前线程会运行;thread apply <ID1> <ID2> <command>
:让一个或者多个线程执行GDB命令command;
参考
GDB调试入门指南
gdb调试多线程程序总结
GDB学习笔记
学习使用 GDB 调试代码
linux下gdb调试方法与技巧整理
100个gdb小技巧