? 个人主页:Zfox_
? 系列专栏:C++从入门到精通
目录
一: ? 什么是GDB / CGDB 二: ? CGDB的安装 ? Linux-centos 三: ? cgdb的使用背景 ? 下面是Makefile中的内容,用于自动化编译: 四: ? CGDB调试代码----指令学习? ? 生成调试文件? 指令集汇总? 指令演示 五: ? 总结六: ? 共勉
一: ? 什么是GDB / CGDB
? GDB
是 Linux
下非常好用且强大的调试工具,GDB
允许开发者在程序运行时检查其内部状态、控制程序的执行流程,并帮助定位和解决程序中的错误(bug
)。
? CGDB
是一款轻量级的基于GDB
的命令行可视化工具,在终端窗口中以图形化的形式来调试代码,非常方便。相对于GDB
来说,可以很大的提高效率
二: ? CGDB的安装
? Linux-centos
? 检查机器上是否安装了cgdb
。 [root@hcss-ecs-a9ee ~]# cgdb --version-bash: cgdb: command not found
? 出现像上⾯的结果,Linux
会友好地告诉你 cgdb
没有安装。安装
cgdb
: sudo yum install -y cgdb
三: ? cgdb的使用背景
⚡ 程序的发布方式有两种,debug
模式和 release
模式。⚡ Linux gcc/g++出来的二进制程序,默认是release
模式。⚡ 要使用cgdb
调试,必须在源代码生成二进制程序的时候, 加上 -g
选项。 ? 下面是Makefile中的内容,用于自动化编译:
1 myexe:code.c2 gcc -o $@ $^ -std=c99 -g 3 .PHONY:clean4 clean:5 rm -f myexe
四: ? CGDB调试代码----指令学习?
? 下面是本次调试所要使用到的代码:
#include <stdio.h>int Sum(int s, int e){ int sum = 0; int i = s; for(; i <= e; i++) { sum += i; } return sum;}int main(){ printf("process is running\n"); int start = 1; int end = 100; int result = Sum(start, end); printf("process is done, result: %d\n", result); return 0;}
? 生成调试文件
不调试的情况下,使用 gcc
指令编译文件一般是:gcc test.c -o test
但是,如果要调试,那么就必须要加上 -g
指令。其原理用 Visual Studio Code
环境下来类比,使用该 IDE
熟悉的话便知道 发行一个程序的时候,可以有 release
版本和 debug
版本,只有我们选择 debug
版本的时候,程序才可以被调试,否则不行。这里也类似,加上 -g
就相当于生成 debug
版本的程序,不加就默认是 release
版本的。其正确指令如下:
gcc test.c -o test -g -std=c99
? 指令集汇总
? 指令集汇总因为这个调试器是在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) + 编号 | 使一个断点有效【开启断点】 |
enable breakpount | 使一个断点有效【开启断点】 |
n(next) | 逐过程【相当于F10】 |
s(step) | 逐语句【相当于F11】 |
bt | 看到底层函数调用的过程【函数压栈】 |
set var | 修改变量的值 |
p(print) 变量名 | 打印变量值 |
display | 跟踪查看一个变量,每次停下来都显示它的值【变量/结构体…】 |
undisplay + 变量名编号 | 取消对先前设置的那些变量的跟踪 |
名字 | 描述 |
---|---|
until + 行号 | 进行指定位置跳转,执行完区间代码 |
finish | 在一个函数内部,执行到当前函数返回,然后停下来等待命令 |
c(continue) | 从一个断点处,直接运行至下一个断点处【VS下不断按F5】 |
? 指令演示
[lisi@hcss-ecs-a9ee lesson9]$ lscode.c Makefile myexe[lisi@hcss-ecs-a9ee lesson9]$ cgdb myexe
首先我们进入到 cgdb
,然后它会等待我们输入指令✨行号显示
l(list) 行号/函数名 —— 显示对应的code,每次10行
首先若是直接【L】的话便会显示出该源文件中的10行内容,这不是我们想要的。
[?1034h[?1034hGNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7Copyright (C) 2013 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "x86_64-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/lisi/112/lesson9/myexe...done.(gdb) l23 printf("process is running\n");242526 int start = 1;27 int end = 100;28 int result = Sum(start, end);29 printf("process is done, result: %d\n", result);30 return 0;31}(gdb)
若是【L 0】或者是【L 1】的话那就是从第一行开始往下列10行的内容
注意这里的L是小写,而且与数字之间要有一个空格
(gdb) L01#include <stdio.h>234int Sum(int s, int e)5{6 int sum = 0;7 int i = s;8 for(; i <= e; i++)9 {10 sum += i;(gdb)
接下去若是想要看到我们所写的全部代码,只需要多Enter
几次就可以了,cgdb
会自动记忆你上次敲入的指令。 其他指令也是如此,大家多多实验即可
五: ? 总结
最后来总结一下本文所学习的内容?
gcc/g++
而言默认生成的可执行程序就是 【Release】
版本的,因此我们要加上一个 -g
命令选项使其在make之后生成一个 【DeBug】
版本的可执行程序,这样就可以进行调试了。接着我们正式进入到了调试器 CGDB
的使用,介绍了很多相关的指令,这些都是我整理出来的常见指令,其实对于 CGDB
来说还有很多指令,但是真正常用的也就这些,只要你认真地看下来,将它们都使用熟练了,相信你的调试功底会大幅度提升,对你在 VS
中的调试也是有所帮助的。最后,在学习了 CGDB
的许多调试指令后,我们便进行了 【Swap Two Numbers】
的实战演练,不仅巩固了C语言中有关传址调用以及函数栈帧的相关指知识,而且使我们对于调试器 CGDB
的使用更上一层楼↑。 六: ? 共勉
以上就是我对 【Linux】精通GDB
的理解,觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~?