GDB入门系列2
一、help命令的使用
1 | ubuntu@VM-0-14-ubuntu:~/learn_gdb$ gdb |
1 | (gdb) help |
1 | (gdb) help breakpoints |
二、关于Tab自动补全
- 补全用于命令(输入字符后按两下Tab,显示所有该字符开头的命令)
1
2(gdb) b
backtrace bookmark break break-range bt1
2(gdb) n
new-ui next nexti ni nosharedlibrary - 补全用于函数名(输入b ma后按下Tab会自动补全为b main)
三、在GDB中运行unix的shell程序
shell
1 | (gdb) shell ls |
四、其它关于GDB调试
1. 设置程序运行参数
为了尝试设置运行参数,我更改了tst的代码,更改的部分如下所示。
1 | ... |
1 | (gdb) set args yemufi pdzhu |
2. 设置运行环境
1 | path <dir> 可设定程序的运行路径。 |
1 | (gdb) show paths |
3. 设置工作目录
1 | (gdb) cd dirA |
4. 程序的输入输出
1 | info terminal 显示你程序用到的终端的模式。 |
1 | (gdb) set args yemufi pdzhu big |
以下是outfile的内容(之前代码最后的/n我已经改成了\n),很奇怪没有打印出输入参数相关的内容!
1 | result[1-100] = 5050 |
5. 调试已经运行的程序
1、在UNIX下用ps查看正在运行的程序的PID(进程ID),然后用gdb
2、先用gdb
6. 断点相关
6.1设置断点
break
在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。break
在指定行号停住。break +offset
在当前行号的前面的offset行停住。offiset为自然数。break -offset
在当前行号的后面的offset行停住。offiset为自然数。break filename:linenum
在源文件filename的linenum行处停住。break filename:function
在源文件filename的function函数的入口处停住。break *address
在程序运行的内存地址处停住。break
break命令没有参数时,表示在下一条指令处停住。break … if
…可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。
6.2 查看断点时(n表示断点号)
- info breakpoints [n]
- info break [n]
6.3 维护停止点
- clear
清除所有的已定义的停止点。 - clear
清除所有设置在函数上的停止点。 - clear filename:function
清除所有设置在函数上的停止点。 - clear
清除所有设置在指定行上的停止点。 - clear filename:linenum
清除所有设置在指定行上的停止点。 - delete [breakpoints] [range…]
删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。 - disable [breakpoints] [range…]
比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止点。简写命令是dis. - enable [breakpoints] [range…]
enable所指定的停止点,breakpoints为停止点号。 - enable [breakpoints] once range…
enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动disable。 - enable [breakpoints] delete range…
enable所指定的停止点一次,当程序停止后,该停止点马上被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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88(gdb) break 20
Breakpoint 1 at 0x11d7: file tst.c, line 20.
(gdb) break 30
Breakpoint 2 at 0x1210: file tst.c, line 30.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000011d7 in main at tst.c:20
2 breakpoint keep y 0x0000000000001210 in main at tst.c:30
(gdb) disable breakpoints 1
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep n 0x00000000000011d7 in main at tst.c:20
2 breakpoint keep y 0x0000000000001210 in main at tst.c:30
(gdb) disable breakpoints 1-2
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep n 0x00000000000011d7 in main at tst.c:20
2 breakpoint keep n 0x0000000000001210 in main at tst.c:30
(gdb) enable breakpoints once 1-2
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint dis y 0x00000000000011d7 in main at tst.c:20
2 breakpoint dis y 0x0000000000001210 in main at tst.c:30
(gdb) break 31
Breakpoint 3 at 0x1228: file tst.c, line 31.
(gdb) r
Starting program: /home/ubuntu/learn_gdb/tst
Breakpoint 1, main (argc=1, argv=0x7fffffffe148) at tst.c:20
20 j = 1;
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe148) at tst.c:30
30 printf("result[1-100] = %d \n", result);
(gdb) c
Continuing.
result[1-100] = 5050
Breakpoint 3, main (argc=1, argv=0x7fffffffe148) at tst.c:31
31 printf("result[1-250] = %d \n", func(250));
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint dis n 0x00005555555551d7 in main at tst.c:20
breakpoint already hit 1 time
2 breakpoint dis n 0x0000555555555210 in main at tst.c:30
breakpoint already hit 1 time
3 breakpoint keep y 0x0000555555555228 in main at tst.c:31
breakpoint already hit 1 time
(gdb) c
Continuing.
result[1-250] = 31125
[Inferior 1 (process 2996651) exited normally]
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint dis n 0x00005555555551d7 in main at tst.c:20
breakpoint already hit 1 time
2 breakpoint dis n 0x0000555555555210 in main at tst.c:30
breakpoint already hit 1 time
3 breakpoint keep y 0x0000555555555228 in main at tst.c:31
breakpoint already hit 1 time
(gdb) clear 31
(gdb) info breakpoints
Deleted breakpoint 3 Num Type Disp Enb Address What
1 breakpoint dis n 0x00005555555551d7 in main at tst.c:20
breakpoint already hit 1 time
2 breakpoint dis n 0x0000555555555210 in main at tst.c:30
breakpoint already hit 1 time
(gdb) delete breakpoint 1
(gdb) info breakpoints
Num Type Disp Enb Address What
2 breakpoint dis n 0x0000555555555210 in main at tst.c:30
breakpoint already hit 1 time
(gdb) clear
No breakpoint at this line.
(gdb) delete 1-10
No breakpoint number 1.
No breakpoint number 3.
No breakpoint number 4.
No breakpoint number 5.
No breakpoint number 6.
No breakpoint number 7.
No breakpoint number 8.
No breakpoint number 9.
No breakpoint number 10.
(gdb) info breakpoints
No breakpoints or watchpoints.
6.4 停止条件维护
- condition
修改断点号为bnum的停止条件为expression。 - condition
清除断点号为bnum的停止条件。 - ignore
表示忽略断点号为bnum的停止条件count次。
6.5 为停止点设定运行命令
为断点号bnum指写一个命令列表。当程序被该断点停住时,gdb会依次运行命令列表中的命令。
commands [bnum]
… command-list …
end
1 | (gdb) break 23 |
6.6 断点菜单
在C++中,由于函数重载的存在,断点指定函数名可能会有多个函数与之对应。此时如果在该函数设置断点,会弹出菜单让你选择设置断点的具体函数。
6.7 恢复程序运行和单步调试
当程序被停住了,你可以用continue命令恢复程序的运行直到程序结束,或下一个断点到来。也可以使用step或next命令单步跟踪程序。
- continue [ignore-count],c [ignore-count],fg [ignore-count]
恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count表示忽略其后的断点次数。continue,c,fg三个命令都是一样的意思。 - step
单步跟踪,如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编译有debug信息。很像VC等工具中的step in。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。 - next
同样单步跟踪,如果有函数调用,他不会进入该函数。很像VC等工具中的step over。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。 - set step-mode on
打开step-mode模式,于是,在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。 - set step-mod off
关闭step-mode模式。 - finish
运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。 - until 或 u
当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。 - stepi 或 si,nexti 或 ni
以上两条都是单步跟踪一条机器指令!一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。与之一样有相同功能的命令是“display/i $pc” ,当运行完这个命令后,单步跟踪会在打出程序代码的同时打出机器指令(也就是汇编代码)
一个小lab
很好奇next的跳过函数是什么(现在发现这个问题好蠢),next的跳过函数只是把这个函数的运行当作一条语句来处理,实际上还是进入了这个函数。
1 | ... |
1 | (gdb) break 29 |
6.8 信号
6.9 线程
7. 观察点相关
设置观察点
- watch
为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。 - rwatch
当表达式(变量)expr被读时,停住程序。 - awatch
当表达式(变量)的值被读或被写时,停住程序。
查看观察点
- info watchpoints
列出当前所设置了的所有观察点。
观察点的实验
不知道为什么设置观察点以后continue,程序确实暂停了但是不会跳出gdb命令行让你继续输入命令,在我输入ctrl+z之后才会弹出来(就是其中的^Z之后)。
1 | (gdb) break 24 |
8. 设置捕捉点
- catch
当event发生时,停住程序。 - tcatch
只设置一次捕捉点,当程序停住以后,应点被自动删除。 - event是什么?
1、throw 一个C++抛出的异常。(throw为关键字)
2、catch 一个C++捕捉到的异常。(catch为关键字)
3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)
4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)
5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)
6、load 或 load载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用)
7、unload 或 unload卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用)
- 本文标题:gdb入门系列2
- 本文作者:mufiye
- 创建时间:2021-11-22 12:58:45
- 本文链接:http://mufiye.github.io/2021/11/22/gdb入门系列2/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!