Linux调试器gdb的使用

1. 创建一个.c文件

建立一个 test.c 文件

代码如下:

#include <stdio.h>    
    
int addToTop(int top)    
{    
  printf("Enter addToTop\n");    
    
  int sum = 0;    
  for(int i = 1; i < top; i++)    
  {    
    sum = sum + i;    
  }    
  printf("Quit addToTop\n");                                                                                                                                                               
  return sum;    
}    
    
int main()    
{    
  int top = 100;    
    
  int result = addToTop(top);    
  printf("result:%d\n",result);    
  return 0;    
}    

2 创建一个Makefile文件

.c 文件同一目录下建立一个 Makefile 文件

代码如下:

mytest:test.c    
  gcc -o mytest test.c    
    
.PHONY:clean    
clean:    
  rm -f mytest  

在终端输入 make 会出现如下报错,因为目前此编译器支持的语法不是 C99 标准,所以在Makefile 文件中需要添加新的选项,图示如下:

在这里插入图片描述
添加新的选项,代码如下:

mytest:test.c    
gcc -o mytest test.c -std=c99      

.PHONY:clean    
clean:    
rm -f mytest    

再次执行 make,发现可以进行编译并成功生成了可执行二进制文件,之后就可以对其进行调试,图示如下:

在这里插入图片描述

3 调试过程

3.1 创建debug版本的二进制文件

1、在终端输入 gdb test.c 开始进行调试时,会出现报错提示:no debugging symbols found (对应的程序中没有调试信息),图示如下:

在这里插入图片描述
因为在 vs 中发布软件有两种方式–debug 版本和 release 版本,debug 版本就是可被调试的版本,而 release 版本是不可被调试的版本(发布版本)。而 linux 下的 gcc/g++ 默认形成的可执行程序是 release 版本的。

解决办法:


Makefile 文件的编译选项中添加 -g 选项就让 gcc/g++debug 的方式编译程序,代码如下:

mytest:test.c    
gcc -o mytest test.c -g -std=c99      

.PHONY:clean    
clean:    
rm -f mytest    

2、将 release 版本的可执行程序命名为 mytest-release,将 debug 版本的可执行程序命名为 mytest-debug 可以看到两个文件大小不一致,debug 版本的大于 release 版本,图示如下:

在这里插入图片描述

3.2 调试过程

1、在终端输入 gdb mytest-debug 启动 gdb 调试,图示如下:

在这里插入图片描述
2、输入 l 显示代码,输入 l 1 从第一行显示代码,图示如下:

在这里插入图片描述

2、继续按 l 或者回车,代码继续向下显示直到全部打印完,图示如下:


在这里插入图片描述
3、输入指令 r 执行程序到断点处,如果没断点则直接执行程序结束,图示如下:

在这里插入图片描述
4、输入 ”b + 行号“ 设置一个断点,图示如下:

在这里插入图片描述
5、输入 “info + b” 查看断点,图示如下:

在这里插入图片描述
Enb 表示使能端是否打开,如果打开断点就生效,如果关闭就是断点暂时失效,但是断点还在。如果想暂时使断点失效可以使用命令 “disable breakpoint + 断点编号”,图示如下:

在这里插入图片描述
6、输入 “ enable + 断点编号 ” 可以重新打开断点,图示如下:

在这里插入图片描述
7、输入 ”r + 回车“ 运行到断点处,图示如下:

在这里插入图片描述
8、再次执行 “ info + b” 查看断点信息,可以看到断点被命中了1次,图示如下:

在这里插入图片描述
9、使用 “d + 当前断点的编号” 删除断点,图示如下:

在这里插入图片描述
10、输入 “quit” 可以退出 gdb 调试,图示如下:

在这里插入图片描述

3.3 逐语句和逐过程

1、逐过程:
输入 n 进行逐过程调试。在 gdb 调试中,如果想逐过程调试输入 n 说明直接把函数跑完到达下一行。逐过程指的是以函数为单位不进入函数,直接把函数当成一条语句执行完,然后到函数的下一行,图示如下:

在这里插入图片描述
2、逐语句:
逐语句的作用就是找到哪个函数出现问题,然后再进入函数逐语句进行调试。输入 s 进行逐语句调试,逐语句就是进入函数一句一句的进行调试,进入addToTop 函数需要记住两点:调用函数需要将该函数的调用数据进行压栈,并且将调试位置变成整个代码中的第一行,图示如下:

在这里插入图片描述

3.4 查看函数调用链

使用命令 bt 查看函数调用链,由于函数调用的过程就是压栈的过程,main 函数在栈底,调用了一个 addToTop 函数,把其放在 main 函数之上,图示如下:

在这里插入图片描述

3.5 查看变量的值

使用 ” p + 变量名称 “ 查看变量值,但是想看变量的变化情况需要一直输入 p,不方便,图示如下:

在这里插入图片描述
所以需要输入 “ display + 字段名称 ” 进行长显示(可以显示内置类型、结构体等自定义类型、stl),设置好长显示的值后,每次单步执行就更新变量值,如下图所示:

在这里插入图片描述
如果不想继续监视某一变量,就输入 “undisplay + 编号 ” 取消字段监视,图示如下:

在这里插入图片描述

3.6 until 指令介绍及使用

如果不想打断点,仅仅想把循环跑完就停下,此时输入 “ until 11 ” 将代码直接运行到11行就停下来,图示如下:

在这里插入图片描述

3.7 finish指令介绍及使用

gdb 还可以不打断点单独将一个函数运行完,进入需要调试的函数并输入指令 “ finish ”,图示如下:

在这里插入图片描述

3.8 从一个断点跳到另一个断点

如果有两个断点,想要从一个断点跳到另一个断点处可以执行命令 c ,直接从一个断点跳到另一个断点处,图示如下:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值