【Linux】gdb工具,Linux 下程序调试的 “透视眼”

目录

调试代码

  • 这是本次调试要用的代码
c 复制代码
  1 #include <stdio.h>
  2 
  3 int AddToTop(int top)
  4 {
  5     printf("Enter AddToTop\n");
  6 
  7     int count = 0;
  8     for(int i = 1;i <= top; ++i)
  9     {
 10        count += i;
 11     }
 12 
 13     printf("Quit AddToTop\n");                                                                         
 14     return count;
 15 }
 16 
 17 int main(void)
 18 {
 19     int top = 100;
 20     int ret = AddToTop(top);
 21 
 22     printf("ret = %d\n", ret);
 23     return 0;
 24 }
  • 下面是Makefile中的内容,用于自动化编译
bash 复制代码
  1 mytest:test.c                                                                                                                                                                                                                    
  2   gcc test.c -o mytest -std=c99 -g 
  3 .PHONY:clean
  4 clean:
  5   rm -rf mytest
  • 注:-std=c99表示以c99的标准来编译代码

调试注意事项

其实对于我们刚才直接make自动化生成的可执行程序是通过gcc直接编译产生得到的,它是一个【Release】版本的可执行程序,因此无法进行调试

  • 但若是我们想要去生成一个【DeBug】版本的可执行程序也是可以的,只需要修改一下我们的Makefile即可,gcc后面带上一个-g的命令选项,此时再去make一下的话生成的就是【DeBug】版本的了, 我们才能进行调试给

gdb和Cgdb

  • 这篇文章我们以Cgdb的形式演示命令,我也更推荐大家去用cgdb,他和gdb的功能是一样的,而且cgdb是可以在上面直接看到代码的,比gdb要方便很多。
  • 指令:cgdb 可执行程序名 (一定要注意是可执行程序文件)

调试命令汇总

  • 因为这个调试器是在Linux环境下的,是纯命令行模式,所以会有很多的指令,做好心里准备😢
    注:()括号里面是该指令的全称

l(list) 行号/函数名 ------ 显示对应的code,每次10行

r(run) ------ F5【无断点直接运行、有断点从第一个断点处开始运行】

b(breakpoint) + 行号 ------ 在那一行打断点

b 源文件:函数名 ------ 在该函数的第一行打上断点

b 源文件:行号 ------ 在该源文件中的这行加上一个断点吧

info b ------ 查看断点的信息

breakpoint already hit 1 time【此断点被命中一次】

d(delete) + 当前要删除断点的编号 ------ 删除一个断点【不可以d + 行号】

若当前没有跳出过gdb,则断点的编号会持续累加 d + breakpoints ------ 删除所有的断点

disable b(breakpoints) ------ 使所有断点无效【默认缺省】

enable b(breakpoints) ------ 使所有断点有效【默认缺省】

disable b(breakpoint) + 编号 ------ 使一个断点无效【禁用断点】

enable b(breakpoint) + 编号 ------ 使一个断点有效【开启断点】

相当于VS中的空断点 enable breakpount ------ 使一个断点有效【开启断电】

n(next) ------ 逐过程【相当于F10,为了查找是哪个函数出错了】

s(step) ------ 逐语句【相当于F11,】

bt ------ 看到底层函数调用的过程【函数压栈】

set var ------ 修改变量的值

p(print) 变量名 ------ 打印变量值

display ------ 跟踪查看一个变量,每次停下来都显示它的值【变量/结构体...】

undisplay + 变量名编号 ------ 取消对先前设置的那些变量的跟踪

排查问题三剑客🗡

until + 行号 ------ 进行指定位置跳转,执行完区间代码 finish ------ 在一个函数内部,执行到当前函数返回,然后停下来等待命令

c(continue) ------ 从一个断点处,直接运行至下一个断点处【VS下不断按F5】

行号显示

  • l(list) 行号/函数名 ------ 显示对应的code,每次10行
  • 首先若是直接【L】的话便会随机显示出该源文件中的随机10行内容,这不是我们想要的

若是【L 0】或者是【L 1】的话那就是从第一行开始往下列10行的内容

断点设置

  • b + 行号 ------ 在那一行打断点
  • b 源文件:函数名 ------ 在该函数的第一行打上断点
  • b 源文件:行号 ------ 在该源文件中的这行加上一个断点

查看断点信息

  • info b ------ 查看断点的信息
  • 若是我们查看一下所打的断点的信息,那就在后面加个b/breakpoint

删除断点

  • d + 当前要删除断点的编号 ------ 删除一个断点【不可以d + 行号】
  • d + breakpoints ------ 删除所有的断点

开启 / 禁用断点

  • disable b(breakpoints) ------ 使所有断点无效【默认缺省】
  • enable b(breakpoints) ------ 使所有断点有效【默认缺省】
  • disable b(breakpoint) + 编号 ------ 使一个断点无效【禁用断点】
  • enable b(breakpoint) + 编号 ------ 使一个断点有效【开启断点】

运行 / 调试

  • r(run) ------ F5【无断点直接运行、有断点从第一个断点处开始运行】
  • 再加上断点去运行的话就会在打的断点处停下来

逐过程和逐语句

  • n(next) ------ 逐过程【相当于F10,为了查找是哪个函数出错了】
  • s(step) ------ 逐语句【相当于F11,一次走一条代码,可进入函数,同样的库函数也会进入】

打印 / 追踪变量

p(print) 变量名 ------ 打印变量值

  • 都执行了那么多次了,不知道【i】和【count】发生了怎样的变化,将它们打印出来看看吧💻
  • 通过继续执行【n】,然后再去打印就可以发现i的值和count的值发生了变化

但是你不觉得这样每次去打印会显得很繁琐吗,那一定会的,所以我们有更好的办法💡

  • display ------ 跟踪查看一个变量,每次停下来都显示它的值【变量/结构体...】
  • undisplay + 变量名编号 ------ 取消对先前设置的那些变量的跟踪

指定行号跳转

  • until + 行号 ------ 进行指定位置跳转,执行完区间代码
  • 可以看到,当前在for循环内容执行累加的逻辑,但若是我们一直这么执行下去,就没有时间排错了,除了上面的哪一种【set var】之外,还有一种方法其实起到直接结束当前循环的作用,那就是进行指定行号跳转
  • 通过观察下图可以看到,当我们运行了until 13之后,程序直接就给出了我们最终的结果count,而且即将要执行最后的打印语句,说明我们跳转成功了
  • 但是注意的是,until并不能跳过断点,如果我们跳过的语句中有断点,until是会听在断点哪里的

强制执行函数

  • finish ------ 在一个函数内部,执行到当前函数返回,然后停下来等待命令
  • 有时候我们会有这样的需求,在初步排查的时候推断可能是某个函数内部的逻辑出了问题,但是呢又不想一步步地进到函数内部进行调试,在VS中其实很简单,只需要在函数下方设个断点,然后F5直接运行到断点处即可

补充命令

watch

  • 执⾏时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB 会暂停程序的执⾏,并通知使⽤者
  • 如果你有⼀些变量不应该修改,但是你怀疑它修改导致了问题,你可以watch它,如果变
    化了,就会通知你.

set var 替换变量值

  • 对于这个修改变量的值,很像是在VS里调试之前设置的那种条件断点,可以使调试开始后直接运行到此断点处。不过对于【set var】而言是在调试过程中进行设置

条件断点

end

感谢大家的阅读,希望对你有帮助,谢谢

相关推荐
什么半岛铁盒4 分钟前
Linux信号的保存
linux·运维·网络
百锦再12 分钟前
大数据技术的主要方向及其应用详解
大数据·linux·网络·python·django·pygame
2301_8035545226 分钟前
vim,gcc/g++,makefile,cmake
linux·编辑器·vim
noravinsc32 分钟前
国产化中间件 替换 nginx
运维·nginx·中间件
惜.己1 小时前
Linux常用命令(十四)
linux·运维·服务器
linkingvision2 小时前
H5S 视频监控AWS S3 对象存储
linux·运维·aws·视频监控s3对象存储
doupoa2 小时前
Fabric 服务端插件开发简述与聊天事件监听转发
运维·python·fabric
BillKu2 小时前
服务器多JAR程序运行与管理指南
运维·服务器·jar
QQ2740287562 小时前
BlockMesh Ai项目 监控节点部署教程
运维·服务器·web3
belldeep2 小时前
WSL 安装 Debian 12 后,Linux 如何安装 vim ?
linux·debian·vim