【Linux】Linux环境下GDB调试

【Linux】Linux环境下GDB调试


前言

GDB: The GNU Project Debugger,GDB调试器诞生于 GNU 计划,是 Linux 下常用的程序调试器。

利用GDB调试器主要实现的功能:

  1. 启动程序,指定任何可能影响其行为的内容,可以按照我们自定义的要求运行程序,例如设置参数和环境变量
  2. 让程序停在指定的条件。
  3. 检查程序停止时发生了什么,查看当前程序的运行状态(例如当前变量的值,函数的执行结果等),即支持断点调试;
  4. 更改程序中的内容,这样就可以尝试纠正一个错误的影响,并继续了解另一个错误。程序执行过程中,可以改变某个变量的值,还可以改变代码的执行顺序,从而尝试修改程序中出现的逻辑错误。

GDB支持的语言:Ada、Assembly、C、C++、D、Fortran、Go、Objective-C、OpenCL、Modula-2、Pascal、Rust


一、GDB命令初探

1.1 进入/退出GDB调试

gdb 【exefilename】:进入GDB调试
(gdb) quit:退出GDB调试
注意:
只有编译时加上-g命令的可执行文件才可以进行GDB调试

[vvvcxjvvv@localhost GDB_Demo]$ g++ GDBTest.cpp -o test_withoutg
[vvvcxjvvv@localhost GDB_Demo]$ g++ -g GDBTest.cpp -o test_withg
[vvvcxjvvv@localhost GDB_Demo]$ gdb test_withoutg
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/vvvcxjvvv/Desktop/cxj_data/GDB_Demo/test_withoutg...(no debugging symbols found)...done.
(gdb) quit
[vvvcxjvvv@localhost GDB_Demo]$ gdb test_withg
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/vvvcxjvvv/Desktop/cxj_data/GDB_Demo/test_withg...done.
(gdb) quit

1.2 获取帮助信息

(gdb)help(h) + 【命令】: 查看命令帮助

1.3 运行

(gdb)run(r) : 重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)
(gdb)run argv[1] argv[2]:调试时命令行传参
(gdb)start :单步执行,运行程序,停在第一行执行语句
(gdb)next(n) :单步调试(逐过程,函数直接执行)
(gdb)step(s):单步调试(逐语句:跳入自定义函数内部执行)
(gdb)finish:结束当前函数,返回到函数调用点
(gdb)continue( c ):继续运行

1.4 查看

(gdb)list(l):查看源代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数)
(gdb)info(i):查看函数内部局部变量的数值
(gdb)print( p ):打印值及地址
(gdb)display:追踪查看具体变量值
(gdb)undisplay:取消追踪观察变量
(gdb)info breakpoints:查看当前设置的所有断点
(gdb)watch:被设置观察点的变量发生修改时,打印显示
(gdb)i watch:显示观察点
(gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元

1.5 断点

(gdb)break+num(b):在第num行设置断点
(gdb)info breakpoints:查看当前设置的所有断点
(gdb)delete breakpoints num(d):删除第num个断点
(gdb)enable breakpoints:启用断点
(gdb)disable breakpoints:禁用断点

1.6 函数

(gdb)backtrace(bt) :查看函数的调用的栈帧和层级关系
(gdb)frame(f):切换函数的栈帧
(gdb)info(i):查看函数内部局部变量的数值
(gdb)finish:结束当前函数,返回到函数调用点

1.7 变量

(gdb)set:设置变量的值
(gdb)display:追踪查看具体变量值
(gdb)undisplay:取消追踪观察变量
(gdb)watch:被设置观察点的变量发生修改时,打印显示
(gdb)i watch:显示观察点

二、使用

测试代码

  1 #include <iostream>
  2 using namespace std;
  3 
  4 int main(){
  5     int sum = 0;
  6     int factorial = 1;
  7     for(int i = 1; i <= 10; i++){
  8         sum += i;
  9         factorial *= i;
 10     }
 11     cout << "sum: " << sum << endl;
 12     cout << "factorial: " << factorial << endl;
 13     return 0;
 14 }

使用GDB进行调试

(gdb) run
Starting program: /home/vvvcxjvvv/Desktop/cxj_data/GDB_Demo/test_withg 
sum: 55
factorial: 3628800
[Inferior 1 (process 4820) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64 libgcc-4.8.5-44.el7.x86_64

run运行代码

(gdb) b 8
Breakpoint 1 at 0x40083c: file GDBTest.cpp, line 8.
(gdb) b 9
Breakpoint 2 at 0x400842: file GDBTest.cpp, line 9.

在8、9行添加断点

(gdb) r
Starting program: /home/vvvcxjvvv/Desktop/cxj_data/GDB_Demo/test_withg 

Breakpoint 1, main () at GDBTest.cpp:8
8	        sum += i;

使用run再次运行代码,在第一个断点处停下

(gdb) print sum
$1 = 0
(gdb) print factorial
$2 = 1
(gdb) p i
$3 = 1

打印变量值

(gdb) c
Continuing.

Breakpoint 2, main () at GDBTest.cpp:9
9	        factorial *= i;    
(gdb) c
Continuing.

Breakpoint 1, main () at GDBTest.cpp:8
8	        sum += i;

使用continue继续执行代码,代码在下一个断点处停下

(gdb) display i
1: i = 2
(gdb) c
Continuing.

Breakpoint 2, main () at GDBTest.cpp:9
9	        factorial *= i;    
1: i = 2
(gdb) c
Continuing.

Breakpoint 1, main () at GDBTest.cpp:8
8	        sum += i;
1: i = 3
(gdb) c
Continuing.

Breakpoint 2, main () at GDBTest.cpp:9
9	        factorial *= i;    
1: i = 3

使用display追踪查看变量i的值

(gdb) list -2
1	#include <iostream>
2	using namespace std;
3	
4	int main(){
5	    int sum = 0;
6	    int factorial = 1;
7	    for(int i = 1; i <= 10; i++){
8	        sum += i;
9	        factorial *= i;    
10	    }

使用list查看源代码

(gdb) display sum
2: sum = 6
(gdb) display factorial
3: factorial = 2
(gdb) c
Continuing.

Breakpoint 1, main () at GDBTest.cpp:8
8	        sum += i;
3: factorial = 6
2: sum = 6
1: i = 4
(gdb) c
Continuing.

Breakpoint 2, main () at GDBTest.cpp:9
9	        factorial *= i;    
3: factorial = 6
2: sum = 10
1: i = 4
(gdb) c
Continuing.

Breakpoint 1, main () at GDBTest.cpp:8
8	        sum += i;
3: factorial = 24
2: sum = 10
1: i = 5
(gdb) 

使用display继续追踪查看变量


附录:常用命令表

命令(简写)描述
$(gdb)help(h)查看命令帮助,具体命令查询在gdb中输入help + 命令
$(gdb)run( r )重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)
$(gdb)start单步执行,运行程序,停在第一行执行语句
$(gdb)list(l)查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数)
$(gdb)set设置变量的值
$(gdb)next(n)单步调试(逐过程,函数直接执行)
$(gdb)step(s)单步调试(逐语句:跳入自定义函数内部执行)
$(gdb)backtrace(bt)查看函数的调用的栈帧和层级关系
$(gdb)frame(f)切换函数的栈帧
$(gdb)info(i)查看函数内部局部变量的数值
$(gdb)finish结束当前函数,返回到函数调用点
$(gdb)continue( c )继续运行
$(gdb)print( p )打印值及地址
$(gdb)quit(q)退出gdb
$(gdb)break+num(b)在第num行设置断点
$(gdb)info breakpoints查看当前设置的所有断点
$(gdb)delete breakpoints num(d)删除第num个断点
$(gdb)display追踪查看具体变量值
$(gdb)undisplay取消追踪观察变量
$(gdb)watch被设置观察点的变量发生修改时,打印显示
$(gdb)i watch显示观察点
$(gdb)enable breakpoints启用断点
$(gdb)disable breakpoints禁用断点
$(gdb)x查看内存x/20xw 显示20个单元,16进制,4字节每单元
$(gdb)run argv[1] argv[2]调试时命令行传参
$(gdb)set follow-fork-mode childMakefile项目管理:选择跟踪父子进程(fork())

参考资料

  1. linux中GDB详细使用手册
  2. GDB官方手册
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值