news 2026/7/26 8:56:10

学 Linux_day3 GDB 常用命令速查卡学习资料

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
学 Linux_day3 GDB 常用命令速查卡学习资料

GDB 常用命令速查卡学习资料

(调试器入门 + 六大核心命令)


一、GDB 是什么?为什么要学?

GDBGNU Debugger的缩写,它是一个让你可以逐行运行程序、随时停下来检查变量值、查看函数调用栈的工具。

如果不使用调试器,程序出错时你只能看着代码干瞪眼,或者在代码里插入无数printf。有了 GDB,你就可以:

  • 让程序在指定的地方暂停(设置断点)
  • 一条一条语句地执行,观察变量的变化
  • 在程序崩溃时,查看崩溃时的现场(调用栈、变量值)

GDB 是命令行工具,功能极其强大,我们今天先掌握最常用的六个命令。


二、调试前的准备:用-g编译

要让 GDB 能读懂你的程序,编译时必须加上-g选项,它会把调试信息(比如源代码行号、变量名等)嵌入到可执行文件中。

编译命令

gcc-ghello.c-ohello

如果不加-g,GDB 里看不到源代码,只能看到汇编指令,调试起来很痛苦。

启动 GDB

gdb ./hello

之后就会进入 GDB 的交互界面,提示符是(gdb),你在这里输入命令。


三、六大核心命令逐一精讲

1.break(简写b)—— 设下断点,让程序停住

作用
在程序执行到某一行代码或某个函数时暂停,方便我们检查当时的程序状态。

常用形式

写法含义
break 行号在当前文件的指定行暂停
break 函数名在进入指定函数时暂停
break 文件名:行号在某个文件的指定行暂停(用于多文件项目)
break 行号 if 条件条件断点,只有条件满足时才暂停

例子

(gdb) break main # 在 main 函数入口暂停 (gdb) break 12 # 在第12行暂停 (gdb) break calc.c:5 # 在 calc.c 的第5行暂停 (gdb) break 20 if x > 5 # 第20行只有当 x>5 时才停

查看已有断点

(gdb) info breakpoints

删除断点

(gdb) delete 断点编号 # 例如 delete 1

2.run(简写r)—— 启动程序开始调试

作用
让程序在 GDB 里开始运行。一旦遇到设置的断点,程序会立即暂停,交还控制权给 GDB。

基本用法

(gdb) run

如果程序需要命令行参数,可以跟在run后面:

(gdb) run arg1 arg2

相当于在终端里执行./hello arg1 arg2

程序一旦暂停,你就可以用其他命令查看当前状态了。


3.next(简写n)—— 逐行执行,不进入函数内部

作用
执行当前代码的下一行,如果这一行里有函数调用,next直接执行完整个函数,不会进入函数体内。可以理解为“单步越过”。

什么时候用
当你确定某函数没问题,不想进去细看它的内部执行时,就用next

例子

(gdb) break main (gdb) run Breakpoint 1, main () at hello.c:5 5 int x = 10; (gdb) next 6 int y = add(x, 5); # 假设 add 是一个函数 (gdb) next # 直接执行完 add,不会进入 add 内部 7 printf("%d\n", y);

如果当前行是add(x,5),按next后程序直接执行完add,然后停在下一行。


4.step(简写s)—— 逐行执行,会进入函数内部

作用
next类似,也是执行下一行,但如果当前行有函数调用,step会“钻”进那个函数里,停在函数的第一条语句上。可以理解为“单步进入”。

什么时候用
当你怀疑某个函数内部有问题,需要进去逐行查看时,就用step

例子

(gdb) break main (gdb) run Breakpoint 1, main () at hello.c:5 5 int x = 10; (gdb) step 6 int y = add(x, 5); (gdb) step # 此时会进入 add 函数内部 add (a=10, b=5) at hello.c:12 12 return a + b;

注意:如果当前行没有函数调用,stepnext的效果是一样的。


5.print(简写p)—— 查看变量或表达式的值

作用
在程序暂停时,查看某个变量当前的值,或者计算一个表达式的值。

基本用法

(gdb) print 变量名 (gdb) print 表达式

示例

(gdb) break main (gdb) run Breakpoint 1, main () at hello.c:7 7 int sum = x + y; (gdb) print x $1 = 10 (gdb) print y $2 = 20 (gdb) print x + y $3 = 30 (gdb) print sum $4 = 0 # 因为 sum 这行还没执行,所以还是初始值 0

$1$2等是 GDB 给每次打印结果分配的编号,后面可以用$1直接引用之前的值。


6.backtrace(简写bt)—— 查看函数调用栈

作用
显示当前程序执行到了哪里,以及它是经过哪些函数调用到达当前位置的。在程序崩溃(Segmentation fault)时极其有用。

基本用法

(gdb) backtrace

输出是一个栈帧列表,最上面是当前正在执行的函数,往下面是调用它的上层函数,再下层是更早的调用者。

示例
假设func_c()崩了,我们用bt查看:

(gdb) backtrace #0 0x00005555555551a5 in func_c () at prog.c:15 #1 0x0000555555555185 in func_b () at prog.c:10 #2 0x0000555555555165 in func_a () at prog.c:5 #3 0x0000555555555145 in main () at prog.c:20

这告诉我们:main调用了func_afunc_a调用了func_bfunc_b调用了func_c,问题就出在func_c里的第15行。


四、GDB 调试实战演示

我们以一个简单的有 bug 的程序为例,完整走一遍调试流程。

源代码buggy.c

#include<stdio.h>intdivide(inta,intb){returna/b;// 如果 b 是 0 就会崩溃}intmain(){intx=10;inty=0;intz=divide(x,y);printf("Result: %d\n",z);return0;}

1. 带调试信息编译

gcc-gbuggy.c-obuggy

2. 启动 GDB

gdb ./buggy

3. 设置断点在 main 函数

(gdb) break main Breakpoint 1 at 0x1145: file buggy.c, line 7.

4. 运行程序

(gdb) run Starting program: /tmp/buggy Breakpoint 1, main () at buggy.c:7 7 int x = 10;

5. 用next逐行执行,观察变量

(gdb) next 8 int y = 0; (gdb) next 9 int z = divide(x, y); (gdb) print x $1 = 10 (gdb) print y $2 = 0

发现y是 0,这会导致除法错误。

6. 用step进入divide函数

(gdb) step divide (a=10, b=0) at buggy.c:4 4 return a / b;

现在我们可以确认b是 0。

7. 查看调用栈(如果此时崩溃,就可以用bt
我们可以先next让它崩溃:

(gdb) next Program received signal SIGFPE, Arithmetic exception.

现在用backtrace看看:

(gdb) backtrace #0 divide (a=10, b=0) at buggy.c:4 #1 0x... in main () at buggy.c:9

立刻知道崩溃在divide函数的第4行,由main第9行调用,且参数b=0。这就是 GDB 的价值。


五、✅ GDB 常用命令速查卡

命令简写作用示例
breakb设置断点b main,b 12,b file.c:5
runr启动程序(可带参数)r,r arg1
nextn执行下一行,不进入函数内部n
steps执行下一行,会进入函数内部s
printp打印变量或表达式的值p x,p a+b
backtracebt显示函数调用栈bt

其他常用小命令(了解即可):

  • continuec):继续运行到下一个断点
  • quitq):退出 GDB
  • listl):显示当前行附近的源代码
  • info locals:显示当前函数的所有局部变量

六、巩固练习

请创建一个新的 C 程序debug_practice.c,内容如下:

#include<stdio.h>intsquare(intn){intresult=n*n;returnresult;}intmain(){inta=5;intb=square(a);intc=square(b);printf("a=%d, b=%d, c=%d\n",a,b,c);return0;}

练习步骤(要求用 GDB 完成并观察每一步):

  1. -g编译程序。
  2. 启动 GDB,设置断点在square函数。
  3. 运行程序,在square第一次被调用时暂停。
  4. print n查看参数n的值。
  5. next执行int result = n * n;,然后用print result查看结果。
  6. backtrace查看是从哪里调用的square
  7. continue让程序继续运行,直到第二次调用square暂停,再次用print nbt观察不同之处。
  8. 最后用continue让程序运行结束,退出 GDB。

参考答案(关键观察点)

  • 第一次到square时,n=5bt会显示#0 square, #1 main
  • 执行完result赋值后,result=25
  • 第二次到square时,n=25(因为 b=25),bt仍类似。
  • 全程没有崩溃,但你能体会到断点和打印的配合。

七、学习检查清单

在结束之前,问自己这几个问题,能答出来就说明你真正掌握了:

  1. 设置断点有哪几种写法?如何删除一个断点?
  2. nextstep的区别是什么?什么时候必须用step
  3. 程序崩溃后,哪个命令能最快定位崩溃的函数和行号?
  4. 如何查看当前函数里某个局部变量的值?
  5. 启动 GDB 时,要求可执行文件必须有什么特殊信息?编译时加什么选项?

如果都可以流畅答出,恭喜你,GDB 的入门调试你已经拿下。之后遇到任何 C 程序问题,都可以拿出这六张速查卡来逐步排查,就像用lscd一样自然。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/26 8:53:24

风电功率预测:CNN-BiLSTM-Attention模型与RIME优化实践

1. 风电功率预测的技术挑战与创新方案 风电功率预测一直是新能源领域的关键技术难题。传统方法往往面临气象数据维度高、时序特征复杂、非线性关系难以捕捉等痛点。最近我在一个实际项目中尝试将霜冰优化算法(RIME)与CNN-BiLSTM-Attention混合模型结合&#xff0c;意外获得了不…

作者头像 李华
网站建设 2026/7/26 8:52:12

ROS2 Node节点——机器人系统中的最小执行单元

面试的时候被问&#xff1a;"ROS2里的Node是什么&#xff1f;它和进程的关系是什么&#xff1f;" 我说"Node就是一个进程"。面试官说&#xff1a;"那一个进程里能不能跑多个Node&#xff1f;"我愣住了。 这是ROS2的基础概念&#xff0c;但很多…

作者头像 李华
网站建设 2026/7/26 8:51:13

C++11 initializer_list:花括号初始化的核心机制与实战应用

1. 项目概述&#xff1a;为什么我们需要initializer_list&#xff1f;在C的日常开发中&#xff0c;尤其是构建容器类或者需要灵活初始化对象时&#xff0c;你是否曾羡慕过像std::vector<int> vec {1, 2, 3, 4, 5};这样简洁直观的初始化方式&#xff1f;在C11标准之前&am…

作者头像 李华
网站建设 2026/7/26 8:50:51

JavaEE-核心知识

JavaEE 核心知识点复习笔记承接上篇 JavaSE&#xff0c;这篇把 JavaEE 从前端基础、数据库、JDBC、反射注解到 SSM 全家桶、SpringBoot、微服务整条线串一遍&#xff0c;面试复习速查专用。一、前端基础&#xff08;JavaWeb 必备&#xff09; 1. 前端三件套 jQuery技术作用HTM…

作者头像 李华
网站建设 2026/7/26 8:50:44

【关注可白嫖源码】--课程设计--毕业设计--springboot咖啡销售系统[编号:project71706](案件分析)

本文仅展示核心实现逻辑与部分代码片段&#xff0c;完整项目源码、配套文档、数据库脚本内容较多&#xff0c;篇幅有限无法全部放出。 有需要完整资源的同学&#xff0c;可以在评论区留言【资料或领源码】&#xff0c;我会一 一回复站内私信&#xff0c;发送完整文件 摘 要 咖啡…

作者头像 李华