欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 【Linux】gdb工具,Linux 下程序调试的 “透视眼”

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

2025/4/26 2:58:07 来源:https://blog.csdn.net/apple_61439616/article/details/147519115  浏览:    关键词:【Linux】gdb工具,Linux 下程序调试的 “透视眼”

目录

  • 调试代码
  • 调试注意事项
  • gdb和Cgdb
  • 调试命令汇总
    • 行号显示
    • 断点设置
    • 查看断点信息
    • 删除断点
    • 开启 / 禁用断点
    • 运行 / 调试
    • 逐过程和逐语句
    • 打印 / 追踪变量
    • 指定行号跳转
    • 强制执行函数
  • 补充命令
    • watch
    • set var 替换变量值
    • 条件断点
  • end

调试代码

  • 这是本次调试要用的代码
  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中的内容,用于自动化编译
  1 mytest:test.c                                                                                                                                                                                                                    2   gcc test.c -o mytest -std=c99 -g 3 .PHONY:clean4 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

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词