GDB调试总结
1.GDB简介
gdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。 GDB主要来调试C/C++语言写的程序,当然也就可以调试其他语言程序。
2.GDB的操作对象
GDB调试的调试对象是可执行文件,不是最初的.c文件。即使用gcc进行编译命令:
gcc -g 源文件.c -o 可执行文件
// -g :打开调试用的 ,加个-g 就是为了gdb 用,不然gdb用不到
// -o :指定输出文件
启动调试:
- gdb 可执行文件
- 先输入gdb,然后指定文件 file 可执行文件
3.常用命令
命令 | 缩写 | 功能 |
---|---|---|
help | h | 查看命令帮助 |
file | 装入需要调试的程序(必须是可执行程序) | |
run | r | 重新开始运行文件 |
info | i | 显示信息,具体看补充1 |
list | l | 查看原代码(list-n,显示以第n行为中心的10行代码。list+ 函数名:查看具体函数) |
start | st | 开始单步调试,在main函数的第一条语句前面停下来 |
next | n | 单步调试(如果该语句为函数调用,不会进入函数内部执行) |
step | s | 单步调试(如果该语句为函数调用,则进入函数执行其中的第一条语句) |
continue | c | 继续运行,直到遇到下一个断点 |
set | 设置变量的值。 set var name =v;例:set var p=1; | |
p | 打印值及地址,具体看补充2 | |
display | disp | 跟踪查看某个变量,每次停下来都显示它的值 |
undisplay | 取消追踪观察变量 | |
watch | 监视变量值的变化(被设置观察点的变量发生修改时,打印显示) | |
i watch | 显示观察点 | |
break line | b | 在第line行设置断点 |
info breakpoints | 查看当前设置的所有断点 | |
delete breakpoints num | 删除第num个断点,简写d | |
enable breakpoints | 启用断点 | |
disable breakpoints | 禁用断点 | |
backtrace | bt | 产看函数调用信息(堆栈) |
frame | f | 查看栈帧 |
finish | 结束当前函数,返回到函数调用点 | |
kill | k | 终止正在调试的程序 |
quit | q | 退出GDB环境 |
补充1:info
3. info args :打印出当前函数的参数名及其值。
4. info locals:打印出当前函数中所有局部变量及其值。
5. info catch :打印出当前的函数中的异常处理信息。
6. info line: 查看源代码在内存中的地址。
info line后面可以跟“行号”,“函数名”,“文件名:行号”,“文件名:函
数名”,这个命令会打印出所指定的源码在运行时的内存地址,如:
```cpp
(gdb) info line tst.c:func
Line 5 of "tst.c" starts at address 0x8048456 <func+6> and ends at 0x804845d <func+13>.
```
- info break :查看断点信息。
- info threads :看正在运行程序中的线程信息
- info registers :查看寄存器的情况。(除了浮点寄存器)
- info all-registers :查看所有寄存器的情况。(包括浮点寄存器)
- info registers :查看所指定的寄存器的情况。
补充2:print
-
可以输出东西可多,全局变量,静态全局变量,局部变量,
//查看全局变量,利用::,例如在1.c中看x gdb)p "1.c"::x
-
数组(动态)p *array@len,array:数组的首地址,len:数据的长度
(gdb) p *array@len $1 = {1, 2, 3, 4, 5}
-
数组(静态) 直接 p 数组名
-
查看指定的寄存器的值, p $eip
4.操作实例
// demo.c
#include <stdio.h>
1 void test(char *str)
2 {
3 printf("str= :%s\n",str );
4 }
5 void main(int argc,char *argv[]){
6 int i,j;
7 j=0;
8 for(i=0;i<10;i++){
9 j+=5;
10 printf("now a=%d\n", j);
11 }
12 }
操作一 (list)
(gdb) list 8
3 {
4 printf("debug info :%s\n",str );
5 }
6 main(int argc,char *argv[]){
7 int i,j;
8 j=0; //以此为中心
9 for(i=0;i<10;i++){
10 j+=5;
11 printf("now j=%d\n", j);
12 }
(gdb)break 10 (在第十行设置断点)
Breakpoint 1 at 0x40050a: file demo.c, line 10.
(gdb)run (重新执行)
Starting program: /mnt/hgfs/www/c/gcc/e
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10 j+=5;
(gdb) c (执行,直到断点处)
Continuing.
now j=5
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10 j+=5;
(gdb)c(执行,直到断点处)
Continuing.
now j=10
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10 j+=5;
(gdb) b 9 (在第九行再加断点)
Breakpoint 2 at 0x400501: file demo.c, line 9.
(gdb)info breakpoints(查看现在的所有断点)
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040050a in main at e.c:10
2 breakpoint keep y 0x0000000000400501 in main at e.c:9
(gdb)delete break 2 (删除第二个断点)
操作二 (display)
(gdb) break 10
Breakpoint 1 at 0x40050a: file demo.c, line 10.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/demo
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10 j+=5;
(gdb) display j (查看参数 j的值)
1: j = 0
(gdb) c
Continuing.
now j=5
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10 j+=5;
1: j = 5
(gdb) display (显示j值)
1: j = 5
(gdb) display i
2: i = 1
(gdb) display j
3: j = 5
(gdb) display j*2
4: j*2 = 10
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
4: y j*2
3: y j
2: y i
1: y j
操作三 (next、step、bt)
(gdb) break 11
Breakpoint 1 at 0x40050a: file demo.c, line 11.
(gdb) r (重新执行)
(gdb) s (单步调试,进函数)
12 printf("now j=%d\n", j);
(gdb) s
__printf (format=0x400648 "now j=%d\n") at printf.c:30
(gdb) bt (产看函数调用信息(堆栈))
#0 __printf (format=0x400648 "now j=%d\n") at printf.c:30
#1 0x0000000000400525 in main (argc=1, argv=0x7fffffffe538) at e.c:12
(gdb) n (单步调试,不进函数)
34 va_start (arg, format);
(gdb) n
35 done = vfprintf (stdout, format, arg);
(gdb) n
now j=5
39 }
(gdb) n
debug info :x=======x
10 for(i=0;i<10;i++){
(gdb) s
Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at e.c:11
11 j+=5;
操作四 (watch)
(gdb) b main
Breakpoint 1 at 0x4004fa: file demo.c, line 9.
(gdb) r
(gdb) watch j (监视变量j,当j变化时,显示监测变量的变化)
Hardware watchpoint 2: j
(gdb) c
Continuing.
Hardware watchpoint 2: j
Old value = 0
New value = 5
main (argc=1, argv=0x7fffffffe538) at demo.c:12
12 printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=5
debug info :x=======x
Hardware watchpoint 2: j
Old value = 5
New value = 10
main (argc=1, argv=0x7fffffffe538) at e.c:12
12 printf("now j=%d\n", j);
操作五(print)
//demo.c
1 #include <stdio.h>
2 void debug(char *str)
3 {
4 printf("debug info :%s\n",str );
5 }
6
7 main(int argc,char *argv[]){
8 int i,j;
9 j=0;
10 for(i=0;i<10;i++){
11 j+=5;
12 printf("now j=%d\n", j);
13 debug("x=======x");
14 }
15 }
(gdb) break main
Breakpoint 1 at 0x4004fa: file demo.c, line 9.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1
Breakpoint 1, main (argc=1, argv=0x7fffffffe538) at demo.c:9
9 j=0;
(gdb) watch i
(gdb) watch j
(gdb) c
Continuing.
Hardware watchpoint 3: j
Old value = 0
New value = 5
main (argc=1, argv=0x7fffffffe538) at demo.c:12
12 printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=5
debug info :x=======x
Hardware watchpoint 2: i
Old value = 0
New value = 1
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at demo.c:10
10 for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j
Old value = 5
New value = 10
main (argc=1, argv=0x7fffffffe538) at demo.c:12
12 printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=10
debug info :x=======x
Hardware watchpoint 2: i
Old value = 1
New value = 2
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at demo.c:10
10 for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j
Old value = 10
New value = 15
main (argc=1, argv=0x7fffffffe538) at demo.c:12
12 printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=15
debug info :x=======x
Hardware watchpoint 2: i
Old value = 2
New value = 3
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at demo.c:10
10 for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j
Old value = 15
New value = 20
main (argc=1, argv=0x7fffffffe538) at demo.c:12
12 printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=20
debug info :x=======x
Hardware watchpoint 2: i
Old value = 3
New value = 4
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at demo.c:10
10 for(i=0;i<10;i++){
(gdb) set var i=8 (设置变量i的值为8)
(gdb) c
Continuing.
Hardware watchpoint 3: j
Old value = 20
New value = 25
main (argc=1, argv=0x7fffffffe538) at demo.c:12
12 printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=25
debug info :x=======x
Hardware watchpoint 2: i
Old value = 8
New value = 9
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at demo.c:10
10 for(i=0;i<10;i++){
(gdb) c
Continuing.
Hardware watchpoint 3: j
Old value = 25
New value = 30
main (argc=1, argv=0x7fffffffe538) at demo.c:12
12 printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=30
debug info :x=======x
Hardware watchpoint 2: i
Old value = 9
New value = 10
0x0000000000400533 in main (argc=1, argv=0x7fffffffe538) at demo.c:10
10 for(i=0;i<10;i++){
https://blog.csdn.net/zdy0_2004/article/details/80102076?ops_request_misc=&request_id=&biz_id=102&utm_term=gdb&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-80102076.first_rank_v2_pc_rank_v29&spm=1018.2226.3001.4187