Saturn

The devil is in the details.

0%

GDB_HELLO_WORLD

GDB单步跟踪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
gdb + 可执行二进制程序
r + 参数列表
b + 断点行数
bt 显示堆栈信息
print 打印表达式值
continue 在一个断点之后继续执行
list 列出源码的一部分
next 在停止之后单步执行
set 设置变量的值
step 进入函数调用
watch 监视一个函数的值
rwatch 监视变量被读暂停程序
awatch 监视变量被读写暂停程序
disable 消除断点
display 在断点停止的地方显示表达式的值
enable 允许断点
finish 继续执行直到函数返回
ignore 忽略断点的次数
info 查看信息
load 动态加载程序到调试器
whatis显示变量的值和类型
ptype 显示变量的类型
return 强制从当前函数返回
make 不退出gdb即可重新产生可执行文件
shel 不退出gdb即可执行linux shell命令
help
quit

常用参数

参数 解析
-e 指定可执行文件名
-c 指定coredump文件
-d 指定目录加入到源文件搜索路径
–cd 指定目录作为路径运行gdb
-s 指定文件读取符号表
-p 指定attach进程

调试进程

1
2
gdb -p 进程名
gdb attach 进程名

调试线程

1
2
info thread //列出已允许的进程下的线程
thread 线程号 //切换到线程

查看相关信息

1
2
3
4
5
(gdb) info  thread    //列出线程
(gdb) info  register  //列出寄存器
(gdb) info  frame  //列出栈帧
(gdb) info  files  //列出当前文件
(gdb) info  share  //列出当前共享库

指定程序允许参数

1
2
set args 1 2 3 4
show args

其他参数

1
2
3
4
5
6
7
8
9
path 设定程序的允许路径
show path
set environment K=v 设置环境变量
show environment 查看环境变量
show language 查看语言环境
info frame 查看函数的程序语言
info source 查看当前文件的程序语言
info breakpoints 显示所有断点
info terminal 显示程序用到的终端模式

添加断点

1
2
3
4
5
6
7
break function 进入指定函数时停住
break n 在指定行号停住
break +offset / -offset 在行号后offset行停住或者前offset行停住
break filename:linenum filename的linenum行停住
break filename:function 同理
break *address 在程序运行的内存地址处停住
break 没有参数时表示在下一条指令处停住

删除断点

1
2
3
delte n 删除n号断点
delte 删除所有断点
clear 删除行n上面的所有断点

程序调试

1
2
3
4
5
6
7
run/r 程序执行直到遇到断点
continue/c 程序执行直到遇到下个断点
next/n 执行下条语句
step/s 单步进入
finish 跳出当前函数
jump location 直到下一条语句的运行点
print/p 输出变量值

输出

1
2
3
4
5
6
7
(gdb) print num
(gdb) p num
(gdb) print file::variable
(gdb) print function::variable
(gdb) p *array@len
$1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}
#静态数组直接print + 数组名就可以打印内容

源代码显示

1
2
3
4
5
6
7
8
9
10
命令	解析
list n 显示程序第n行的周围的源程序。
list function 显示函数名为function的函数的源程序。
list +n 显示当前行n后面的源程序。
list -n 显示当前行n前面的源程序。
set listsize 设置一次显示源代码的行数。
show listsize 查看当前listsize的设置。
# 查看源代码的内存地址
(gdb) info line tst.c:func
Line 5 of "tst.c" starts at address 0x8048456 and ends at 0x804845d .

查看内存地址保存的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
你可以使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:

(gdb) x/nfu addr
1
n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是
指令地址,那么格式可以是i。
u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可
以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当
我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作
一个值取出来。
addr表示一个内存地址。
n/f/u三个参数可以一起使用。例如:

(gdb) x/3uh 0x54320 //从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。

查看寄存器

1
2
info registers
info all-registers

显示堆栈

1
2
3
4
5
6
(gdb) backtrace [-full] [n]
/*命令产生一张列表,包含着从最近的过程开始的所有有效过程和调用这些过程的参数。
n:一个整数值,当为正整数时,表示打印最里层的 n 个栈帧的信息;n为负整数时,那么表示打印最外层n个栈帧的信息;
-full:打印栈帧信息的同时,打印出局部变量的值
注意,当调试多线程程序时,该命令仅用于打印当前线程中所有栈帧的信息。
如果想要打印所有线程的栈帧信息,应执行thread apply all backtrace命令*/

显示栈帧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
frame 或 f 会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。
查看当前栈帧中存储的信息

(gdb) info frame
Stack level 0, frame at 0x7ffc1da10e80:
rip = 0x7f800008b4e3 in __epoll_wait_nocancel; saved rip = 0x5560eac8b902
called by frame at 0x7ffc1da11280
Arglist at 0x7ffc1da10e70, args:
Locals at 0x7ffc1da10e70, Previous frame's sp is 0x7ffc1da10e80
Saved registers:
rip at 0x7ffc1da10e78

该命令会依次打印出当前栈帧的如下信息:
1、当前栈帧的编号,以及栈帧的地址;
2、当前栈帧对应函数的存储地址,以及该函数被调用时的代码存储的地址
3、当前函数的调用者,对应的栈帧的地址;
4、编写此栈帧所用的编程语言;
5、函数参数的存储地址以及值;
6、函数中局部变量的存储地址;
7、栈帧中存储的寄存器变量,例如指令寄存器(64位环境中用 rip 表示,32为环境中用eip 表示)、
堆栈基指针寄存器(64位环境用 rbp表示,32位环境用 ebp表示)等。

搜索源代码

1
2
forward-search
reverse-search

设置观察点

1
2
3
watch 	为表达式(变量)expr设置一个观察点。一旦表达式值有变化时,马上停住程序
(gdb) watch i != 10
//这里,i != 10这个表达式一旦变化,则停住。watch <expr> 为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序(也是一种断点)。

设置捕捉点

1
2
3
4
5
6
可设置捕捉点来补捉程序运行时的一些事件。如载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
//catch 当event发生时,停住程序
(gdb) info catch
//打印出当前的函数中的异常处理信息。
(gdb) info locals
//打印出当前函数中所有局部变量及其值。

强制调用函数

1
2
3
4
(gdb) call <expr>
/*这里,<expr>可以是一个函数,这样就会返回函数的返回值,如果函数的返回类型是void那么就不会打印函数的返回值,但是实践发现,函数运行过程中的打印语句还是没有被打印出来。
表达式中可以一是函数,以此达到强制调用函数的目的。并显示函数的返回值,如果函数返
回值是void,那么就不显示。*/

终止

1
2
3
kill 终止正在调试的程序
detach 将gdb和程序分离
q 退出gdb

打印美化

1
set print pretty on