参考:参考博客
- 断点使用
break filename:lineNumber
break … if < condition> ex: break test.c:6 if num>0
break break命令没有参数时,表示在下一条指令处停住
break *0x400522 指定地址断点
break &a 观察变量
x按16进制格式显示变量
d按十进制显示变量
u按十六进制格式显示无符号整形 ex: print /x c
o按八进制格式显示变量
t按二进制格式显示变量
c按字符格式显示变量
f按浮点数格式显示变量
动态数组 p *array@len, 注意len表示长度, 静态数组 直接用数组名 ex: p array@len
set print array on 打开后数组每个元素占一行
打印全局变量 file::variable 有同名局部变量时 ex: p t.c::a
p 'testfile.c'::i
p 'sum'::i
打印指针 print *p@len 打印指针需要加*号,打印多个,后面用@len 指定长度
$可表示上一个变量,在调试链表时时经常会用到的,它有next成员代表下一个节点,则可使用下面方式不断打印链表内容
p *$.next #这里显示linkNode节点下一个节点的内容
set print elements
这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个来指定数据显示的最大长度,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制。
set print pretty on
如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮
set print union
设置显示结构体时,是否显式其内的联合体数据
set print object
在C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB就不管虚函数表了
set 修改变量 ex set sum=56
- 使用examine(简写x)来查看内存地址中的值。语法:
x/
n、f、u是可选的参数。
(1)n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
(2)f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。
(3)u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
eg:
x/3uh 0x54320 :从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示
- display
display: 显示全局变量
ex: display t1 display info display
- list
<+offset> 当前行号的正偏移量。
<-offset> 当前行号的负偏移量。
<filename:linenum> 哪个文件的哪一行。
<function> 函数名。
<filename:function> 哪个文件中的哪个函数。
<*address> 程序运行时的语句在内存中的地址。bash
list first,last ex: l 25,36 l 66
- skip skip可以在step时跳过一些不想关注的函数或者某个文件
skip function [fun]
删除skip,使用skip delete [num]
- watch 当被观察的变量发生变化后,程序就会暂停执行,并把变量的原值(Old)和新值(New)都会显示出来
watch sum 重要
rwatch <expr> 当表达式(变量)expr被读时,停住程序
awatch <expr> 当表达式(变量)的值被读或被写时,停住程序
help里是这么写的,其实awatch是读写断点,内存被读或着写时都会断。而rwatch是读时断,watch是写时断
- finish 退出本函数 缩写为 fin
- info program 使用info program 来查看程序的是否在运行,进程号,被暂停的原因
- delete
clear 清除所有的已定义的停止点
delete [breakpoints] [range…] 删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d
其它
11. info 查看信息
info args 打印出当前函数的参数名及其值。
info locals 打印出当前函数中所有局部变量及其值。
info catch 打印出当前的函数中的异常处理信息
info line tst.c:func
13. condition
14. until 或 u 当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体
3.
信号是一种软中断,是一种处理异步事件的方法。一般来说,操作系统都支持许多信号。尤其是UNIX,比较重要应用程序一般都会处理信号。UNIX定义了许多信号,比如SIGINT表示中断字符信号,也就是Ctrl+C的信号,SIGBUS表示硬件故障的信号;SIGCHLD表示子进程状态改变信号;SIGKILL表示终止程序运行的信号,等等。信号量编程是UNIX下非常重要的一种技术。
GDB有能力在你调试程序的时候处理任何一种信号,你可以告诉GDB需要处理哪一种信号。你可以要求GDB收到你所指定的信号时,马上停住正在运行的程序,以供你进行调试。你可以用GDB的handle命令来完成这一功能。
handle
如果你程序是多线程的话,你可以定义你的断点是否在所有的线程上,或是在某个特定的线程。GDB很容易帮你完成这一工作。
break thread
break thread if … linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB分配的,你可以通过“info threads”命令来查看正在运行程序中的线程信息。如果你不指定thread 则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如:
(gdb) break frik.c:13 thread 28 if bartab > lim
当你的程序被GDB停住时,所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行时,所有的线程也会被恢复运行。那怕是主进程在被单步调试时。
return 使用return命令取消当前函数的执行,并立即返回,如果指定了,那么该表达式的值会被认作函数的返回值
多线程调试可能是问得最多的。其实,重要就是下面几个命令:
info thread 查看当前进程的线程。
thread 切换调试的线程为指定ID的线程。
break file.c:100 thread all 在file.c文件第100行处为所有经过这里的线程设置断点。
set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。