GDB 是什么?
gdb由 GNU 软件系统社区提供的调试工具,同 GCC 配套组成了一套完整的开发环境,GDB 是 Linux 和许多类 Unix 系统中的标准开发环境。
一般来说,GDB 主要完成下面四个方面的功能:
启动程序:可以按照自定义的要求随心所欲的运行程序。
设置断点:可让被调试的程序在所指定的调置的断点处停住,断点可以是条件表达式。
打印信息:当程序被停住时,可以检查此时程序中所发生的事。
修改变量:可以通过修改程序中的变量,将一个 BUG 产生的影响修正从而测试其他 BUG。
gdb各指令说明
1、编译可调试文件
-g
举例:
gcc -g xx.c -o yyyy(输出yyyy可执行文件)
载入编译文件
gdb a.out
2、设置断点
break/b 行号
break/b 函数名
执行在某个线程里打断点:break/b 56 thread 3
3、删除断点
delete
用法:delete [breakpoints num] [range…]
delete可删除单个断点,也可删除一个断点的集合,这个集合用连续的断点号来描述。
例如:
delete 5 (5代表行数) / d 5(5表示第几个断点)
delete 1-10(1到10行的断点)
d 删除所有断点
4、clear
用法:clear
删除所在行的所有断点。
clear location
clear 删除所选定的环境中所有的断点
clear location location描述具体的断点。
例如:
clear ValueCompare // 删除ValueCompare函数的所有断点
clear example.c:ValueCompare // 删除example.c文件:ValueCompare函数的所有断点
clear 12 // 删除行号的所有断点
clear example.c:12 // 删除example.c文件:行号12的所有断点
clear 删除断点是基于行的,不是把所有的断点都删除。
5、单步调试
n :执行下一行程序
s :执行下一行程序,如果遇到函数 直接跳入函数,跳出该函数使用fin/return
6、重新运行调试
restart/r
7、查看info gdb信息
info registers :查看当前寄存器的值
info args :查有当前函数参教的值
info locals :查看当前局部变量的值
info frame :查看当前栈的详细信息
info variables :查看程序中的变量符号
info functionscsd : 查看程序中的函数符号
8、停止结束
quit/q
9、对正在执行的程序进行调试
以下三种方式皆可:
1) gdb attach PID
2) gdb 文件名 PID
3) gdb -p PID
结束方式:
执行 detach 指令,使 GDB 调试器和程序分离;
执行 quit(或 q)指令,退出 GDB 调试。
10、反汇编
disassemble/disass
当在oops里看到汇编指令偏移,可以利用gdb的dissemble指令,看到反汇编,然后逐行找到编译个命令,定位到大概在函数的多少行。
11、查看变量信息命令
print/p
12、display命令(自动显示命令)
和print 命令一样,display 命令也用于调试阶段查看某个变量或表达式的值,它们的区别是,使用 display 命令查看变量或表达式的值,每当程序暂停执行(例如单步执行)时,GDB 调试器都会自动帮我们打印出来,而 print 命令则不会。
查看display的变量数:info display
13、删除自动打印:undisplay num…
14、继续执行
C(continue),不能是r,r代表restart,从头开始执行
15、查看线程信息
info threads
跳转到指定线程:t/thread i(线程号)
16、查看所有线程调用栈:
thread apply all bt
17、gdb内执行shell指令
两种方式:shell command | !command.
第一种是用内置指令shell。
第二种是用特殊符号!开头。
好处就是可以边调试边看源码,甚至进行一些其他操作.
示例:
!less a.cpp
# 查看代码
!pwd
#查看进来时的工作目录
c && !ping 192.168.1.155
#测试发包结构
18、修改调试的变量值
print num = x
19、跳到指定行
jump number(行号)
注意:跳过的不执行
20、指定在某个文件打断点
b file.c:22
21、until(u) 执行一行程序
若此时程序是在 for/while/do loop 循环的最后一行,则一直执行到循环 结束后的第一行程序后停止
在没有循环的地方,可以直接指定到多少行,u line
如:u 53
22、examine(x)
打印内存地址值,格式如下:
x/[ number][ format] < addr>
其中number,format都是可选参数
addr:为查看变量的内存地址
number: 一个正整数,表示从当前地址向后显示几个地址的内容,如
x/24 0x400c90
表示查看0x400c90到向后0x400c90+24的内容
format:显示的格式不是查看的格式。和c语言中的格式缩写一样,如
d:整数integer
s:字符串string
c:字符char
u:无符号整数 unsigned integer
o:八进制格式显示变量
x:十六进制格式
f: 浮点数格式float
23、加载符号表命令
symbol-file [符号表文件]
24、条件断点
watch expr if cond
break expr if cond
25、显示当前行号
info line
26、focus显示命令模式(显示代码窗口,边显示代码边调试)
注意:
切换到 focus模式后,箭头键被用来移动上方的代码窗口。如果需要在调试窗口切到历史命令,可以用
ctrl+p previous
ctrl+n next
ctrl+b back
ctrl+f forward
(gdb) info win
src (31 lines)
cmd (17 lines)
(gdb) fs cmd
Focus set to cmd window.
(gdb) info win
src (31 lines)
cmd (17 lines)
此时,gdb focus在cmd window,箭头会作用于cmd window,想切换回 src window,输入fs src即可。
关闭 : Ctrl+X+A
27、断点条件判断(字符比较)
b 4124 if strcmp(tn->str,“exit”) == 0
28、commonds 命令
给断点附加一些 “自动化” 执行的命令,当程序运行到断点并停住时,就会自动执行这些预先设定好的命令, 达到“自动化调试”的目的。
commands <break_number>
> …command_list…
> end
break_numer:是断点号
end: 结束commands 命令
举例: 遇到断点,自动打印调用栈
(gdb) b free(第一个断点,使用commands时,可以省略1断点号)
Breakpoint 1 at 0x7fba758d54 (3 locations)
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just “end”.
>bt
>c
>end
(gdb) b malloc(为第二个断点)
Breakpoint 2 at 0x7fba758774 (3 locations)
(gdb) commands 2
Type commands for breakpoint(s) 2, one per line.
End with a line saying just “end”.
>bt
>c
>end
(gdb) c
删除:
清空断点的命令,输入commands num后,直接输入end即可
(gdb)commands 1
> end
29、查看变量的类型:(whatis)
(gdb) whatis i
type = u_int8_t
(gdb) whatis u_int8_t
type = __uint8_t
(gdb) whatis __uint8_t
type = unsigned char
30、查看函数传参参数
info/i args
31、gdb return finish
(1)如果想要立即中断当前函数运行并返回,用return,当前函数的剩余语句将不被执行。(return可带参数,可以此随意设定当前函数的返回值)
(2)如果想让程序执行到当前函数返回之后停止,用finish,当前函数的剩余语句将会正常运行。
32、gdb 进程传参
–args
例如:
gdb --args ./trdp-md-test caller
trdp-md-test:进程
caller :参数
33、打印设置
(1)set print address on/off:是/否打印地址
(2)set print symbol_filename on/off:是/否打印文件名和行号
(3)set print array on:以习惯格式打印数组
(4)set print array-indexes on打印数组时打印每个数组成员的下标。
(5)set print elements number-of-elements:设置gdb打印数组成员数量(0表示无限制)
(6)set print pretty on:结构体格式化输出
34、查看堆栈:bt
35、跳转到某个线程: t/thread 线程号
36、设置字符串打印不限制长度:set print elements 0
37、在GDB中设置库路径:
(gdb) set solib-search-path /home/user/libs
设置多个路径:
set solib-search-path /home/user/libs:/usr/local/lib (各个库路径通过冒号“:”分隔)
38、加载core文件:
(1)gdb live core: live为进程名,core为core文件
(2)gdb live(进程名): core-file core文件
39、gdb和shell环境切换:(1)gdb->shell: shell。(2)shell->gdb:exit
40、线程锁定/解锁:set scheduler-locking on/off
41、info proc mappings:获取正在调试的进程的内存映射信息。
42、加载分离符号表:
(1)找到动态库的起始地址:info sharedlibrary
(2)add-symbol-file libXXX.so.sym 动态库起始地址
(3)进程内加载core分离符号:symbol-file core coredump.sym