【Linux基础开发工具】Linux调试器-gdb

发布时间:2023年12月28日

目录

前言

1. 背景

2. 基本使用

总结


前言

????????GDB(GNU Debugger)是一个功能强大的开源调试器,它用于调试C、C++等程序,在Linux环境下软件开发的过程中,调试是一个至关重要的环节。无论是在开发新的软件还是维护现有的代码,都难免会遇到各种各样的bug和问题,所有学会使用调试器是非常有必要的。

在这里插入图片描述

1. 背景

????????程序的发布方式有两种,Debug模式和release模式

为什么要存在两种?

????????Debug模式通常用于开发阶段,它会保留所有的调试信息,包括符号表、断点和日志,以便开发人员可以轻松地调试和定位问题。此外,Debug模式通常会关闭一些优化选项,以便在开发过程中能够更快地构建和运行程序。这样可以加快开发人员的迭代速度,提高开发效率

????????release模式则用于最终发布产品的版本。它会启用各种优化选项,以提高程序的性能和减小体积。同时,release模式会删除所有的调试信息,从而减小程序的体积和保护源代码不被泄露。这样可以确保最终发布的产品具有更好的性能和安全性

Linux gcc/g++编译程序默认是什么模式?

在默认的情况下,Linux gcc/g++出来的二进制程序,默认是release模式

gcc的默认行为:

  • 默认动态链接
  • 默认release发布

如何以Debug模式下发布?

在使用gcc/g++编译时加上 -g选项 比如:

gcc -o mytest test.c -g

查看可执行程序添加的调试信息:

readelf指令(elf为可执行程序的格式)比如:

readelf -S mytest | grep -i debug

?结果如下:

2. 基本使用

在此之前需要先确保Linux机器上是否安装gdb,安装指令:

sudo yum install -y gdb

进入调试:

gdb binFile//binFile也就是编译后产生的可执行程序

Linux版本基本调试功能:

  • 运行起来才能调试(r)

  • 调试时可以看到代码(l)

  • 打断点/删除断点(b 断点位置、d 断点编号)

  • 关闭/开启断点(enable、disable)

  • 局部调试(finish、until、c)

  • 看到/取消 局部变量的内容和地址(display、undisplay)

  • 看到调用栈(bt)

  • 单步执行(s)

  • 逐过程执行(n)

  • 打印变量值(p)

  • 在调试过程中修改变量的值(set var)

?后续示例使用的代码:

#include<stdio.h>

int Sum (int n)
{
  int i = 1;
  int sum = 0;
  for(; i <= n; i++)
  {
    sum +=i;
  }
  return sum;
}
int main()
{

  printf("hello world!\n");
  //……

  int ret = Sum(100);

  printf("%d\n",ret);

  return 0;
}

Linux调试器gdb:

  • l 行号:显示指定行之后的代码(gdb自动记录最近一条指令)

点击回车可以继续查看后边的代码

  • 打断点:在指定位置打断点

b 行号

b 文件名:行号

b 函数名

  • 查看断点:info b

  • 关闭断点:disable 断点编号

此时编号为1的断点已被关闭,keep后边属性显示n(no)

  • 开启断点:enable 断点编号

  • r开始调试:直接跳到断点位置

直接跳转到了第一个断点位置

  • 逐语句 s(可进入函数)

  • 逐过程 n(逐行执行)

  • quit:退出gdb

  • display 变量的内容和地址:跟踪查看一个变量,每次停下来都显示它的值

每次逐语句执行时都输出了sum和i的值

  • undisplay 编号:取消常显示变量的内容和地址

  • c 直接跳到下一个断点

重新开始调试,r直接执行到第一个断点位置,c执行到下个断点

  • d 断点编号:删除断点
  • finish:执行完当前函数并返回,然后停下来

我们调试进入Sum函数,可以通过finish指令检查Sum函数,finish指令让Sum函数立即执行完毕,并返回返回值

  • breaktrace(或bt):查看各级函数调用及参数

  • until 行号:跳至对应行(范围执行)

重新调试进入Sum函数的循环

我们发现代码一直卡在9行和7行,我们又不想立即执完函数,就要求立即执行完循环,这时就可以使用until

直接跳到11行,这样就可以直接执行完循环?

  • p 变量:打印变量值。

(gdb) p sum 
$2 = 5050
  • set var 变量:修改变量的值(不用修改代码,测试其他分支)

比如我们在测试if语句分支时

if(flag==1)...

else ...

如果代码中以及规定flag值为1,但是又不想重新打开代码进行修改,这时就可以使用set var

比如:

set var flag=0

就可以直接修改flag的值来测试另一条分支


总结

? ? ? ? 在软件开发的过程中,无论是初学者还是经验丰富的开发人员,都会遇到各种各样的bug和问题,学会使用gdb,可以极大地提高代码调试的效率和准确性,好了以上便是本文的全部内容,感谢阅读!

文章来源:https://blog.csdn.net/2202_75605090/article/details/135186683
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。