Linux:gdb的使用
前言:
在linux纯命令行中,我们通常通过使用gdb调试器来调试一个可运行程序,可以通过调试来找到程序崩溃的原因,可以通过函数栈帧的调用来定位哪个函数的错误,所以说掌握好gdb的使用,对于专业的程序员来讲至关重要。本文就来详细讲述一下gdb的最常见的使用命令(本文通过如下代码进行示例讲解)
预备知识:
debug VS release
- debug版本:一个可运行的程序调试是需要配置一些调试信息(例如变量名、行号信息这些等等)这样方便我们调试可以查看到我们想看到的信息,这中配置了调试信息的就叫做debug版本
- release版本:没有配置调试信息,并且编译器还对可执行程序进行了一些优化,这种版本就叫做release版本
所以程序员想要对程序进行调试时,先要将程序变成debug版本
在linux命令行中,在gcc/g++默认编译生成程序的是release版本,所以我们后面要加一个-g选项则可以将程序变成debug版本。
gdb常见命令:
1.开始进入调试:gdb 程序文件名(要带上路径)
ps:这后面的一大段文字都是讲GDB 软件的版权信息和版本说明,只需看最后一行表示我们进入了调试阶段(如果文件不存在最后一行会提示“not such file”),直接开始我们的调试即可
2.设置断点:break(或者'b') 函数名/行编号
ps:注意会给每个断点设置编号,删除断点时要用。
3.运行:run 直接跳转到下一个断点,如果无断点就会直接运行整个程序
这里就直接运行到了第一个断点处,15行的main函数
注意:断点编号只是单纯一个标识,并不是运行是要从第一号断点再到第二号断点,而是要看程序先运行到哪里,比如这次的run就先运行到了第二号断点,而不是第一行断点
4.查看断点信息:info b
- Num:断点的编号
- Enb:表示断点可用
- Address:表示代码行的地址
5.设置断点是否可用:enable/disable b +断点编号
- 断点可用:运行时遇到断点会停下
- 断点不可用:就当断点不存在,遇到了也会接着向下运行
6.取消断点:delete(或者'd') 断点的编号
7.逐过程:step(或者's') 调用函数时会进入函数里
8.逐语句:next(或者'n') 调用函数时不会进入函数里
9.查看变量值:print('p')变量名
10监视窗口:display变量名(每次逐语句或者逐过程时调试时都会显示变量的值)
(':'前面的是监视窗口的编号,删除监视窗口时需要用到)
11.查看函数的调用:bt
12.删除监视窗口:undisplay 窗口编号
这里的删除逻辑跟断点类似
练习案例:
熟悉了gdb的常见命令,就可以尝试自己调试了,可以通过下文的代码简单地练习一下
#include <stdio.h>int add(int a, int b) {int result = a + b;return result;
}int main() {int x = 5;int y = 10;int z = 0; // 这个变量后面会被错误使用printf("开始计算...\n");// 正确的加法int sum = add(x, y);printf("%d + %d = %d\n", x, y, sum);// 有bug的循环 - 多了一次int total = 0;for (int i = 1; i <= 5; i++) { // 应该 i < 5total += i;printf("i=%d, total=%d\n", i, total);}// 未初始化的变量使用int final_result = sum + total + z;printf("最终结果: %d\n", final_result);return 0;
}
总结:
在linux中,熟练掌握gdb的使用方法,让我们更容易定位出错误找到bug所在,帮我们节省大量时间,还有一些可以帮助深入理解程序运行机制的相关命令(例如:info registers查看寄存器内容),让我们加深对程序运行的底层理解。
下图是我做的思维导图,供参考复习
结语:
以上就是我分享的Linux:gdb使用的全部内容了,希望对大家有些帮助,也希望与一样喜欢编程的朋友们共进步
谢谢观看
如果觉得还阔以的话,三连一下,以后会持续更新的,我会加油的
祝大家早安午安晚安