Linux笔记---调试工具GDB(gdb)

种地  金牌会员 | 2024-11-23 06:54:08 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 875|帖子 875|积分 2625

1. gdb的概念

GDB,全称GNU Debugger,是一个功能强大的开源调试工具,广泛用于Unix和类Unix系统,以及Microsoft Windows和macOS平台。GDB允许开辟者在程序实行过程中查看内部运行情况,帮助定位和修复程序中的错误。
gdb的紧张功能:
   

  • 启动和控制程序实行:gdb可以按照自定义要求运行程序,并在指定的断点处暂停实行。
  • 检查程序状态:当程序暂停时,gdb允许开辟者检查程序中发生的事情,包括变量的值、函数的调用堆栈等。
  • 修改变量和程序实行流程:gdb允许开辟者在调试过程中修改变量的值,甚至改变程序的实行路径,以测试不同的情景。
  2. gdb的使用

我们知道,一个程序的代码可以编译出两个版本:release和debug。
在Linux中,我们使用gcc/g++来编译代码Linux笔记---gcc/g++与编译链接-CSDN博客。
当我们使用这两个工具来编译代码时,默认情况下编译出的是release版本,这个版本是无法被调试的。如果想使用gdb来调试我们的代码,需要在编译时带上 [-g] 选项,保留调试信息,生成debug版本的可实行程序。
在命令行输入下面的指令即可开始对可实行程序进行调试:
  1. gdb [可执行程序名] # 注意是对可执行程序进行调试,而不是源代码
复制代码
在接下来的先容中,我们以下面这段代码为例:
  1. #include <stdio.h>
  2. int Sum(int s, int e)
  3. {
  4.     int result = 0;
  5.     for(int i = s; i <= e; i++)
  6.     {
  7.         result += i;
  8.     }
  9.     return result;
  10. }
  11. int main()
  12. {
  13.     int start = 1;
  14.     int end = 100;
  15.     printf("I will begin\n");
  16.     int n = Sum(start, end);
  17.     printf("running done, result is: [%d-%d]=%d\n", start, end, n);
  18.     return 0;
  19. }
复制代码
2.1 cgdb

在Linux中,直接使用gdb来调试程序并不方便,无法做到像在vs中一样对代码进行实时的可视化调试,对程序运行的跟踪非常贫苦:

可以看到,在启动gdb对test程序进行调试时,页面中不会有任何的调试信息,要查看代码都只能通过 [l] 命令来一段一段地查看,就更别说指示当前代码实行到哪一行的箭头了。
以是,我们推荐使用基于gdb的调试工具cgdb来进行调试:
cgdb是一个基于文本的调试工具,它是gdb调试器的一个前端界面,旨在提供一个更加用户友好的调试环境。cgdb团结了gdb的强大调试功能和文本界面的简便性,使得开辟者可以在命令行环境中更高效地进行程序调试。
cgdb的使用方式,各种命令与gdb完全一致,但cgdb相比于gdb还具有以下特点和功能:
   

  • 用户友好的界面:cgdb提供了一个分屏界面,上半部门显示源代码,下半部门显示gdb命令行界面,使得开辟者可以同时查看代码和实行调试命令。
  • 语法高亮:cgdb支持源代码的语法高亮,使得代码更易于阅读和明白。
  • 自动完成:cgdb具有自动完乐成能,可以帮助开辟者更快地输入gdb命令。
  • 汗青命令记载:cgdb记载了之前实行过的命令,开辟者可以方便地调用和重复实行这些命令。
  • 断点管理:cgdb提供了直观的断点管理界面,使得开辟者可以轻松地设置、删除和查看断点。
  • 变量查看:cgdb允许开辟者查看和修改变量的值,以及查看函数的调用堆栈。
  cgdb的安装方式在不同的平台有所不同,在Ubuntu中可使用下面的命令来安装:
  1. sudo apt-get install cgdb
复制代码
使用cgdb再次尝试调试程序:
 可以看到,代码动态地展现在屏幕上半,绿色的箭头动态地对代码的实行进行跟踪,极大地方便了我们对代码进行调试。
接下来我们再详细先容gdb中的各种指令,比方上图中在15行打上断点并让程序运行了起来。
2.2 控制实行的相干指令

命令作用示例
[run] / [r]从头开始一连实行程序,直到碰到断点或程序结束
[next] / [n]逐过程调试,等价于vs中的F10
[step] / 逐步调试,等价于vs中的F11
[finish]实行完当前函数
[set var] + [变量名]=[值]修改某变量的值set var i=10 --- 将i的值修改为10
[continue] / [c]从当前位置开始一连实行程序,直到碰到断点或程序结束
[until] + [行号n]实行到指定行until 20 --- 实行到第20行
[until] + [文件名]:[行号n]实行到指定文件的指定行until test.c:16 --- 实行到test.c的第16行
[quit] / [q]退出gdb/cgdb
2.3 查看信息的相干指令

命令作用示例

    / [l] + [行号n]
显示第n行前后的源代码,每次显示10行l 25 --- 显示25行前后的源代码

    / [l] + [函数名]
显示指定函数的源代码list main --- 显示main函数的源代码

    / [l] + [文件名]:[行号n]
显示指定文件的第n行前后的源代码,每次显示10行,这里的文件指编译形成该可实行程序的源代码文件l test.c:15 --- 显示test.c第15行前后的源代码
[info] / + [breakpoints] / [break] / 查看断点信息列表
[display] + [表达式]跟踪显示表达式的值(每次停止时显示一次)display a+b --- 每次停止时显示a+b的值
[undisplay] + [表达式序号]取消对指定序号表达式的跟踪显示undisplay 1 --- 取消对1号表达式的追踪显示
[backtrace] / [bt]查看当前实行栈的各级函数调用及参数
[info] / + [locals]查看当前栈帧的局部变量
[print] / [p] + [表达式]打印指定表达式的值p a+b --- 打印a+b的值
2.4 断点的相干指令

命令作用示例
[break] / + [行号n]在第n行打断点b 13 --- 在13行打断点
[break] / + [函数名]在指定函数的第一行打断点b main --- 在main函数第一行打断点
[break] / + [文件名]:[行号n]在指定文件的第n行打断点b test.c:17 --- 在test.c的第17行打断点
[delete] / [d] + [断点序号]删除指定序号的断点,不指定时默认删除全部断点d 1 --- 删除序号为1的断点
[delete] / [d] + [breakpoints]删除全部断点d breakpoints --- 删除全部断点
[disable] + [断点序号]禁用指定序号的断点,不指定时默认禁用全部断点disable 2 --- 禁用序号为2的断点
[enable] + [断点序号]启用指定序号的断点,不指定时默认启用全部断点enable 2 --- 启用序号为2的断点
[watch] + [表达式]监督某表达式,当表达式值发生厘革时程序停止并显示厘革前后的值(监督也是一种断点,删除方式与断点相同)watch a+b --- 监督a+b的值
 条件断点

顾名思义,条件断点就是在满足一定条件时断点才见效,断点信息列表中有相应的信息。
命令作用示例
[break] / + [行号n] + [条件]在第n行打条件断点b 13 if result == 64 --- 在第13行打上条件断点,改断点只有在result == 64时才见效
[break] / + [函数名] + [条件]在指定函数的第一行打条件断点
[break] / + [文件名]:[行号n] + [条件]在指定文件的第n行打条件断点
[condition] + [断点序号] + [条件]给平凡断点加上条件condition 2 result == 54 --- 给2号断点设置条件result == 54,使之成为条件断点
注意:在删除指定断点或取消跟踪时要使用序号,而不能使用行号或表达式。断点的行号可以使用 [info] + 查看,表达式的序号会在显示其值时一并显示出来。 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表