一、基本命令
l
(list) :显示代码b + 行号/函数名
(breakpoint):可以使用 文件名:行号 和 类名::方法名 的方式在指定位置加断点delete + 断点号
:删除指定断点clear + 行号
:删除指定断点enable + 断点号
:将断点设定为无效的,不加断点号,将所有断点设置为无效r
(run):运行程序,直到碰到断点n
(next):继续执行下一条语句 ,会把函数当作一条语句执行start
:从main函数第一行代码开始执行,并停在第一行代码s
(step):继续执行下一条语句,会跟踪进入函数,一次一条的执行函数内的代码c
(continue):直接执行到下一个断点finish
:一直执行当前函数,直到碰到断点或执行完当前函数p + 变量名
(print):打印变量值回车
:重复上一行命令q
:退出调试,中止进程info b/break
:显示断点信息bt
:显示函数调用栈disassemble
:显示汇编代码
当调试带命令行参数的程序时,先用 gdb ELF文件 的方式进入调试状态,然后run启动程序时再带上命令行参数
实践调试过程
编译:
gcc -g -Wall -o test test.c
进入gdb调试界面,并在12行打断点
启动程序后,在14行打断点,然后继续运行,这时会先执行13行printf,然后阻塞在14行的断点处
我们打印一下n和g_var的值,看是否和printf的相同
使用s进入函数,finish结束当前函数
我们重新启动程序,进入add函数后bt打印一下函数调用堆栈
再次重新启动程序,删除第17行的断点
gdb attach 进程号
:调试进程
info threads
:显示当前进程的线程信息
thread 线程号
:进入当前线程
调试coredump
访问已经回收的内存,或访问空指针,野指针都会出现coredump,专业的描述是segmentfault
- 打开core文件开关:ulimit -c unlimited,表示不限制core文件大小
- 开始执行业务:发现bin目录下有core文件,该文件中存储的是程序挂之前的一些“遗言”,包括函数调用栈等
- gdb调试core
由于core文件存放的是程序挂掉的一些“遗言”,可读不可写,也不用打断点
还可以bt查看函数调用栈
二、gdb调试release版本死循环
gdb attach到release版本的进程上
attach后,进程就会处于停止态
attach后使用gcore生成记录当前执行状态的core文件
gcore main-release.core
然后detach,退出gdb,此时进程继续执行
先调试一下main-release
换成debug版本的可执行文件,执行到core文件记录的位置
可以根据函数调用栈,定位代码
二、gdb调试release版本死锁
启动进程
拿到进程号并gdb attach
退出后,再利用debug版本的可执行文件调试core文件
切换到出现问题的子线程
如下,可以定位到自己写的某段代码