linux: gdb调试器

故事背景

事实上,gdb调试器,是一个用于我们linux命令行式的调试工具,但是但凡接触过一些vscode或者studio这些图形化的自带图形可视化的调试工具,gdb是确实不好用我还不如自己连一些服务器到vscode呢。 但是gdb依然是功能强大,纯命令行环境下不可或缺的工具哈!所以接下来俺带你看看它咋用!

core: 程序核心转储文件 : 通常用于gdb调试那着core文件可以迅速判断代码的错误信息

进程终止

如果你对进程的终止(是over 不是停止 区别于)情况有足够的了解你可以可以参考上图理解当进程退出的时候如果生成了核心转储文件即在状态码的第8位 core: 变位1 表示生产力状态码

core信息调试

就一句话,当系统生成了core文件,指令

bash 复制代码
gdb 程序名 core文件名
如: gdb test core.file

然后gdb会帮你直接找到程序崩溃的行并打印所在代码上下文

但是要注意一件事: 就是linux系统默认不生成core文件,所以你得打开,一般不打开笔记调试方式千千万抓到鱼的才是好猫咪:

  1. 临时开启:ulimit -c unlimited
  2. 永久生效:修改/etc/security/limits.conf* soft core unlimited~
  3. 也可以这样永久生效 : 就是在~/.bash_profile 启动时候执行的指令

本文就不带你用core去调试了,能用就行!

跟上小哥的节奏咱直接调试一个实例试试

有问题的demo代码

cpp 复制代码
void func(){


  std::cout<<"hello wold";
  int b =2;
  b++;
 

  for(int i=0;i<10;i++){
    int c =2;
       3/b;
        b--;
     
  }

}

int main(){


  int c = 3;
  int b =2;
  c++;
  b--;
  func();



  return 0;
}

提前看出这里代码func函数中当b为0的时候,/0问题进程会收到 SIGFPE

(SIGFPE 是浮点异常信号,FPE=Floating Point Exception;) 信号 我们可以用调试器来找到这个错误的位置 开始吧和我一起用gbd调试器

1.1 基本的命令 /操作

cpp 复制代码
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。

list/l 函数名:列出某个函数的源代码。

r或run:运行程序。

n 或 next:单条执行。

s或step:进入函数调用

break(b) 行号:在某一行设置断点

break 函数名:在某个函数开头设置断点

info break :查看断点信息。

finish:执行到当前函数返回,然后挺下来等待命令

print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数

p 变量:打印变量值。

set var:修改变量的值

continue(或c):从当前位置开始连续而非单步执行程序

run(或r):从开始连续而非单步执行程序

delete breakpoints:删除所有断点

delete breakpoints n:删除序号为n的断点
disable breakpoints:禁用断点
enable breakpoints:启用断点
info(或i) breakpoints:参看当前设置了哪些断点
display 变量名:跟踪查看一个变量,每次停下来都显示它的值
undisplay:取消对先前设置的那些变量的跟踪
until X行号:跳至X行
breaktrace(或bt):查看各级函数调用及参数
info(i) locals:查看当前栈帧局部变量的值
quit:退出gdb

1.2 调试基本操作&理念

首先你要知道gdb的调试真的就是基于命令 与断点来的否则会很不舒服:

基本页面如下:tip: 你编译成员的时候必须加上 -g选项 才能调试哦

提前设置main为断点,其次就是 r运行起来然后s/n 逐语句或者逐过程 直到报错的位置。

如果是逻辑错误你可以用:watch查看变量

1.3 具体调试例子

1. 输入gdb 可执行程序名

进入到该执行页面 ,值得注意的是gdb就是长这样

(gdb) 待输入命令

回显

(gdb)待输入命令

(gdb) q -----------q就退出啦

你会觉得很不习惯,可以先看看代码 如果你不知道代码多少行你可以 尽量大些

2. 显示代码

3. 设置断点(breakpoint)

断点操作合集哈:

  1. 设置断点 : b 行号

b 函数名

  1. 查看所有断点: info b

  2. 删除断点 : delete 序号

我这里先设置main函数为断点 如图

值得注意的是: 调试的时候第一件事是进入程序你要执行run命令

但是run命令会优先跳到第一个断点,所以你的断点要是不设置就直接运行完了,你还调试啥!

所以我这里先把断点设置在main函数

4. run起来

你也可以用r表示run哈 ,进入以后还会贴心的回显一下你所在的位置,上下文也就是执行流到了main已经回显它的上下文

5. 逐过程和逐语句

为了便于调试你可以用list 默认输出当前执行流上下文,默认5行代码,这样便于你调试:

逐行调试/逐语句:

命令 作用 场景
n(next) 逐行执行,跳过函数调用 不想进入 func 函数,只看主流程
s(step) 逐行执行,进入函数内部 想调试 func 函数里的代码(比如执行到 func() 时输 s 就会进入第 22 行)
c(continue) 从当前位置运行到下一个断点 跳过中间代码,直接到下一个断点
finish 执行完当前函数,回到调用处 在 func 内部时,输 finish 回到主函数调用 func 的位置

注意有时候我们的执行流可能跳转到我们的头文件包含的一些库函数,我们直接输入finish即可

继续:

显示上下文 然后逐语句执行 s命令 注意它不会跳过函数,逐过程n 会跳过函数

非常贴心的为你回显每次执行了啥

6. 查看变量值(监视)

用where查看执行流正在执行哪一行:

监视:

|----------------|---------------------------------------------|
| 打印变量值 | p 变量名(比如 p c 查看主函数里的 c 值,支持 p c+b 计算) |
| 实时监视变量 | watch 变量名(比如 watch c,变量值变化时 GDB 会暂停并提示 |
| 查看当前所有局部变量 | info locals(直接输出当前函数内的所有变量值) |

执行到这发现一个简单的问题,就是这是,这就是执行流进入库函数了,你直接finish即可

继续逐过程直到出错

出错了

6. bt可以查看调用栈

查看是谁调用的,以及被调用,也就是查看当前函数是谁以及谁调用了它

相关推荐
CAU界编程小白8 分钟前
Linux系统编程系列之动静态库
linux
北辰当尹9 分钟前
【实习之旅】Kali虚拟机桥接模式ping通百度
java·服务器·桥接模式
济61710 分钟前
linux(第十三期)--filezilla使用方法(实现ubuntu和windows11文件互传)-- Ubuntu20.04
linux·运维·ubuntu
HIT_Weston11 分钟前
91、【Ubuntu】【Hugo】搭建私人博客:侧边导航栏(五)
linux·运维·ubuntu
阿巴~阿巴~13 分钟前
从不可靠到100%可靠:TCP与网络设计的工程智慧全景解析
运维·服务器·网络·网络协议·tcp/ip·智能路由器
oMcLin14 分钟前
如何在 Rocky Linux 8.6 上配置并调优 Nginx 与 Lua 脚本,提升 API 网关的性能与并发处理能力
linux·nginx·lua
飞翔的小->子>弹->15 分钟前
CMK、CEK
服务器·数据库·oracle
Yana.nice22 分钟前
Linux目录结构说明
linux
一殊酒23 分钟前
【Figma】Figma自动化
运维·自动化·figma
EndingCoder27 分钟前
箭头函数和 this 绑定
linux·前端·javascript·typescript