Linux调试:gdb基本使用方法

1、基本使用方法

  Windows上的IDE图形化软件使得程序的调试比较方便,而Linux常用的是gdb命令,它同样可以实现打断点、查看程序运行时某个变量值等等操作,在Ubuntu上默认自带gdb,可以直接调试运行在系统上的应用程序。(注意,需要用到gdb调试的话在编译时需要加上-g选项。)

常用选项如下:
选项 功能
list / l 查看源代码,可跟行号、函数名
break / b 设置断点,可根据行号或函数名,还可以设置条件断点,如:b 10 if i==2
info / i 查看gdb内部局部变量的数值,如:info breakpoints
delete / d 删除断点,不加编号默认删除所有断点,删除编号N的断点:d N
set 设置变量的值,如:set args hello 123 给main函数传参
start 单步执行,停在执行的第一句
run / r 全速运行程序
run argv[1] argv[2] 给main函数传参,如:run hello 123
next / n 逐步运行
step / s 逐步运行,但遇到函数调用时会进到函数内部执行
finish 结束当前函数,回到函数调用点
continue / c 继续全速运行剩下的代码直到下一个断点
print / p 打印变量值、地址
backtrace / bt 查看函数调用的栈帧以及层级关系
frame / f 切换函数的栈帧
display 设置观察变量
undisplay 取消观察变量
enable breakpoints 启用断点
disable breakpoints 禁用断点
watch 被设置观察点的变量发生变化时打印显示
i watch 显示观察点
ptype 查看变量类型,如:ptype i
help / h 按模块列出命令类
help class 查看某一类具体命令
quit / q 退出gdb

2、调试示例

2.1 源码(故意引入一个修改常量引起段错误)
#include <stdio.h>

void A(char *p)
{
    
    
	*p = 2;
}

int main(int argc, char *argv[])
{
    
    
	char i = 0;
	char j = 0;
	char *str = "hello";

	A(&i);
	printf("i = %d\n", i);

	j = 3;

	printf("argv[1] = %s\n", argv[1]);
	printf("j = %d\n", j);

	A(str);
	printf("str = %s\n", str);

	return 0;
}


2.2 调试流程

(注意:发生段错误可以直接使用gdb的run命令即可定位到问题,这里只是演示一下基本步骤。)

book@Ubuntu:~/work/imx6ull/application/01_gdb$ gdb test
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...done.
(gdb) l																	// 列出代码
1       #include <stdio.h>
2
3       void A(char *p)
4       {
    
    
5               *p = 2;
6       }
7
8       int main(int argc, char *argv[])
9       {
    
    
10              char i = 0;
(gdb)
11              char j = 0;
12              char *str = "hello";
13
14              A(&i);
15              printf("i = %d\n", i);
16
17              j = 3;
18
19              printf("argv[1] = %s\n", argv[1]);
20              printf("j = %d\n", j);
(gdb)
21
22              A(str);
23              printf("str = %s\n", str);
24
25              return 0;
26      }
27
(gdb)
Line number 28 out of range; test.c has 27 lines.
(gdb) b 14																// 打断点
Breakpoint 1 at 0x4005d6: file test.c, line 14.
(gdb) b 18																// 打断点
Breakpoint 2 at 0x4005fe: file test.c, line 18.
(gdb) b 19																// 打断点
Note: breakpoint 2 also set at pc 0x4005fe.								// 提示该断点在断点2处已经打了
Breakpoint 3 at 0x4005fe: file test.c, line 19.
(gdb) b 22																// 打断点
Breakpoint 4 at 0x400630: file test.c, line 22.
(gdb) b 5																// 打断点
Breakpoint 5 at 0x40059e: file test.c, line 5.
(gdb) info breakpoints													// 列出断点
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main at test.c:14
2       breakpoint     keep y   0x00000000004005fe in main at test.c:18
3       breakpoint     keep y   0x00000000004005fe in main at test.c:19
4       breakpoint     keep y   0x0000000000400630 in main at test.c:22
5       breakpoint     keep y   0x000000000040059e in A at test.c:5
(gdb) d 2																// 删除编号2的断点
(gdb) info breakpoints													// 再次列出断点,发现断点2被删除了 
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main at test.c:14
3       breakpoint     keep y   0x00000000004005fe in main at test.c:19
4       breakpoint     keep y   0x0000000000400630 in main at test.c:22
5       breakpoint     keep y   0x000000000040059e in A at test.c:5
(gdb) set args test_str													// 给main函数设置参数
(gdb) start																// 启动调试
Temporary breakpoint 6 at 0x4005b7: file test.c, line 9.
Starting program: /home/book/work/imx6ull/application/01_gdb/test test_str

Temporary breakpoint 6, main (argc=2, argv=0x7fffffffe338) at test.c:9
9       {
    
    
(gdb) n																	// 下一步
10              char i = 0;
(gdb) n 																// 下一步
11              char j = 0;
(gdb) print i															// 打印I的值
$1 = 0 '\000'
(gdb) n 																// 下一步
12              char *str = "hello";
(gdb) n 																// 下一步

Breakpoint 1, main (argc=2, argv=0x7fffffffe338) at test.c:14			// 到达14行的函数main的断点
14              A(&i);
(gdb) n 																// 下一步

Breakpoint 5, A (p=0x7fffffffe23e "") at test.c:5						// 到达第5行的函数A的断点
5               *p = 2;
(gdb) n 																// 下一步
6       }
(gdb) n 																// 下一步
main (argc=2, argv=0x7fffffffe338) at test.c:15
15              printf("i = %d\n", i);
(gdb) n 																// 下一步
i = 2
17              j = 3;
(gdb) display i 														// 设置一直显示i的值
1: i = 2 '\002'
(gdb) display j 														// 设置一直显示j的值
2: j = 0 '\000'
(gdb)
(gdb) n 																// 下一步

Breakpoint 3, main (argc=2, argv=0x7fffffffe338) at test.c:19
19              printf("argv[1] = %s\n", argv[1]);
1: i = 2 '\002'
2: j = 3 '\003' 														// 程序执行到19行时就已经等于3了
(gdb) n
argv[1] = test_str
20              printf("j = %d\n", j);
1: i = 2 '\002'
2: j = 3 '\003'
(gdb) n
j = 3

Breakpoint 4, main (argc=2, argv=0x7fffffffe338) at test.c:22
22              A(str);
1: i = 2 '\002'
2: j = 3 '\003'
(gdb) n

Breakpoint 5, A (p=0x4006f4 "hello") at test.c:5
5               *p = 2;
(gdb) n

Program received signal SIGSEGV, Segmentation fault.					// 发生了段错误,查看描述是在test.c文件第5行的A函数赋值时出错
0x00000000004005a2 in A (p=0x4006f4 "hello") at test.c:5
5               *p = 2;
(gdb) n

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) q																	// 退出
book@Ubuntu:~/work/imx6ull/application/01_gdb$

猜你喜欢

转载自blog.csdn.net/weixin_44498318/article/details/111318553