【GDB】GDB调试学习小结

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指令如下:

指令名称简写含义
runr运行程序
quitq退出gdb调试
listl查看我们的源代码(显示行数,方便打断点定位)
breakb打断点
infoi查看信息
nextn继续执行下一个
printp打印变量值
steps进入函数调试

例如运行程序,我们可以输入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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值