Linux gdb调试(1):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$

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R-QWERT

你的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值