0x00 前言
文章中的文字可能存在语法错误以及标点错误,请谅解;
如果在文章中发现代码错误或其它问题请告知,感谢!
GDB version: 8.1.0.20180409-git
系统版本:Ubuntu 18.04.4 LTS \n \l
最后更新:2021-11-19
0x01 学习小结
1.GDB简介
(1)GDB是什么?
GDB, the GNU Project debugger, allows you to see what is going on `inside’ another program while it executes – or what another program was doing at the moment it crashed.
GDB调试器可以运行你在程序运行的时候检查里面到底发生了什么。
(2)GDB解决什么问题?
GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
GDB可以做以下四件事:
- Start your program, specifying anything that might affect its behavior. 监控程序运行
- Make your program stop on specified conditions.打断点,在断点处停止
- Examine what has happened, when your program has stopped.当程序停止时,检查发生了什么
- Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.改变程序一些东西,纠正bug
- Those programs might be executing on the same machine as GDB (native), on another machine (remote), or on a simulator. GDB can run on most popular UNIX and Microsoft Windows variants, as well as on Mac OS X.GDB支持跨平台
2.GDB应用举例
(1)搭建实验环境
- 安装GDB:
Ubuntu:
#apt get-install gdb
CentoOS:
#yum install gdb
- 检查安装是否成功:
#gdb --version
有显示则成功。
(2)GDB调试举例
gdb有多种指令,常用gdb指令如下:
指令名称 | 简写 | 含义 |
---|---|---|
run | r | 运行程序 |
quit | q | 退出gdb调试 |
list | l | 查看我们的源代码(显示行数,方便打断点定位) |
break | b | 打断点 |
info | i | 查看信息 |
next | n | 继续执行下一个 |
p | 打印变量值 | |
step | s | 进入函数调试 |
例如运行程序,我们可以输入run
:
#(gdb)run
退出GDB调试我们可以输入quit
:
#(gdb)quit
调试程序
为了进一步熟悉GDB的使用,我们首先写一个可以运行的代码,代码命名为test.c:
#include<stdio.h>
int main(){
int arr[4] = {1, 2, 3, 4};
int i = 0;
for(i = 0; i < 4; i++){
printf("%d\n", arr[i]);
}
return 0;
}
编译可执行文件test
,注意要加-g
:
#gcc -g -o test test.c
编译好之后,GDB调试运行:
#gdb ./test
进入到GDB调试界面后,我们可以使用
list
查看代码以及代码所在行数,然后对行数进行打断点操作(#break line-nmber
),也可以对函数名打断点(#break func-name
):
若要查看断点信息可以使用
info
指令(#info break
):
若要打印变量值可以使用
print
指令,例如要打印&arr[0]
(print &arr[0]
):
调试子函数
有时候我们需要进入子函数,可以在子函数处设置断点,然后输入step
进入子函数:
#include<stdio.h>
void hello(){
printf("hello world\n");
}
int main(){
int arr[4] = {1, 2, 3, 4};
int i = 0;
for(i = 0; i < 4; i++){
printf("%d\n", arr[i]);
}
hello();
return 0;
}
在hello()
处(在17行)设置断点(#break 17
),然后进入(#step
):
调试core文件
有时候程序出错会生成一个core
文件,通过GDB调试core
文件可以快速定位程序出错位置,一般来说core
文件不会默认生成,需要取消ulimit
限制(#ulimit -c unlimited
)。下面是一段错误代码test_err.c
:
include<stdio.h>
int main(){
int *temp = NULL;
*temp = 10;、
return 0;
}
程序运行时会报错,我们通过GDB查看报错原因:
可以看到第6行是错误原因。
调试正在运行的进程
我们也可以对正在运行的进程进行调试,下面是一段循环运行的代码test_for.c
:
#include<stdio.h>
void test(){
}
void test1(){
int i = 0;
i++;
}
int main(){
for(;;){
test();
test1();
}
return 0;
}
编译并在后台运行:
#gcc -g -o test test_for.c
#./test &
指令执行后获得进程PID
,该例中PID
为2373,此时进入到GDB输入如下指令对该进程进行调试:
#gdb -p 2373
若在GDB调试进程时出现“Could not attach to process
”问题可参考此文档解决:https://blog.csdn.net/weixin_30915951/article/details/98356342
以上。
参考文档:
1.https://www.gnu.org/software/gdb/
2.https://www.bilibili.com/video/BV1EK411g7Li?spm_id_from=333.999.0.0