Linux学习——GDB调试

本文详细介绍了Linux下的程序调试工具GDB的使用,包括GDB的下载安装、调试C/C++程序的步骤、常用调试命令如run、break、watch、catch等的详细用法,以及如何查看栈信息、编辑和搜索源码。GDB作为强大的调试器,能帮助开发者高效地定位和修复逻辑错误。
摘要由CSDN通过智能技术生成

GDB简介

程序中的错误主要分为 2 类,分别为语法错误和逻辑错误:

程序中的语法错误几乎都可以由编译器诊断出来,很容易就能发现并解决;

逻辑错误指的是代码思路或者设计上的缺陷,程序出现逻辑错误的症状是:代码能够编译通过,没有语法错误,但是运行结果不对。
对于这类错误,只能靠我们自己去发现和纠正。

实际场景中解决逻辑错误最高效的方法,就是借助调试工具对程序进行调试。
所谓调试(Debug),就是让代码一步一步慢慢执行,跟踪程序的运行过程。
通过调试程序,我们可以监控程序执行的每一个细节,包括变量的值、函数的调用过程、内存中数据、线程的调度等,从而发现隐藏的错误或者低效的代码。

常用的调试器

调试器名称 特点
Remote Debugger Remote Debugger 是 VC/VS 自带的调试器,与整个IDE无缝衔接,使用非常方便。
WinDbg 大名鼎鼎的 Windows 下的调试器,它的功能甚至超越了 Remote Debugger,它还有一个命令行版本(cdb.exe),但是这个命令行版本的调试器指令比较复杂,不建议初学者使用。
LLDB XCode 自带的调试器,Mac OS X 下开发必备调试器。
GDB Linux 下使用最多的一款调试器,也有 Windows 的移植版。

GDB是什么
GDB 全称“GNU symbolic debugger”,从名称上不难看出,它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。
Windows 操作系统中,人们更习惯使用一些已经集成好的开发环境(IDE),如 VS、VC、Dev-C++ 等,它们的内部已经嵌套了相应的调试器。

借助 GDB 调试器可以实现以下几个功能:

程序启动时,可以按照我们自定义的要求运行程序,例如设置参数和环境变量;

可使被调试程序在指定代码处暂停运行,并查看当前程序的运行状态(例如当前变量的值,函数的执行结果等),
即支持断点调试;

程序执行过程中,可以改变某个变量的值,还可以改变代码的执行顺序,从而尝试修改程序中出现的逻辑错误。

GDB下载和安装

在命令行窗口中执行 gdb -v 命令,判断当前 Linux 发行版是否安装有 GDB 。
在这里插入图片描述
如上所示,执行结果为“command not found”,表明当前系统中未安装 GDB 调试器。

对于尚未安装 GDB 的 Linux 发行版,安装方法通常有以下 2 种:

  1. 直接调用该操作系统内拥有的 GDB 安装包,使用包管理器进行安装。此安装方式的好处是速度快,但通常情况下安装的并非 GDB 的最新版本;

  2. 前往 GDB 官网下载源码包,在本机编译安装。此安装方式的好处是可以任意选择 GDB的版本,但由于安装过程需要编译源码,因此安装速度较慢。

GDB调试C/C++的过程

例:
一段能够正常编译运行的 C 语言程序,文件路径为 /tmp/demo/main.c 。

#include <stdio.h>
int main ()
{
   
    unsigned long long int n, sum;
    n = 1;
    sum = 0;
    while (n <= 100)
    {
   
        sum = sum + n;
        n = n + 1;
    }
    return 0;
} 

使用 gcc -g 选项编译源文件,即可生成满足 GDB 要求的可执行文件。

# gcc main.c -o main.exe -g

启动GDB调试器
在生成包含调试信息的 main.exe 可执行文件的基础上,启动 GDB 调试器的指令如下:

# gdb main.exe

该指令在启动 GDB 的同时,会打印出一堆免责条款。通过添加 --silent(或者 -q、–quiet)选项,可将比部分信息屏蔽掉:

#  gdb main.exe --silent

启动成功的标志就是最终输出的 (gdb)。
通过在 (gdb) 后面输入指令,即可调用 GDB 调试进行对应的调试工作。

GDB常用的调试指令

调试指令 作用
(gdb) break xxx (gdb) b xxx 在源代码指定的某一行设置断点,其中 xxx 用于指定具体打断点的位置。
(gdb) run (gdb) r 执行被调试的程序,其会自动在第一个断点处暂停执行。
(gdb) continue (gdb) c 当程序在某一断点处停止运行后,使用该指令可以继续执行,直至遇到下一个断点或者程序结束。
(gdb) next (gdb) n 令程序一行代码一行代码的执行。
(gdb) print xxx (gdb) p xxx 打印指定变量的值,其中 xxx 指的就是某一变量名。
(gdb) list (gdb) l 显示源程序代码的内容,包括各行代码所在的行号。
(gdb) quit (gdb) q 终止调试。

GDB run(r)命令:启动程序

run 和 start 指令都可以用来在 GDB 调试器中启动程序。
它们之间的区别是:

默认情况下,run 指令会一直执行程序,直到执行结束。
如果程序中手动设置有断点,则 run 指令会执行程序至第一个断点处;

start 指令会执行程序至 main() 主函数的起始位置,
即在 main() 函数的第一行语句处停止执行(该行代码尚未执行)。

在进行 run 或者 start 指令启动目标程序之前,还可能需要做一些必要的准备工作,大致包括以下几个方面:

如果启动 GDB 调试器时未指定要调试的目标程序,或者由于各种原因 GDB 调试器并为找到所指定的目标程序,这种情况下就需要再次手动指定;

有些 C 或者 C++ 程序的执行,需要接收一些参数(程序中用 argc 和 argv[] 接收);

目标程序在执行过程中,可能需要临时设置 PATH 环境变量;

默认情况下,GDB 调试器将启动时所在的目录作为工作目录,但很多情况下,该目录并不符合要求,需要在启动程序手动为 GDB 调试器指定工作目录。

默认情况下,GDB 调试器启动程序后,会接收键盘临时输入的数据,并将执行结果会打印在屏幕上。
但 GDB 调试器允许对执行程序的输入和输出进行重定向,使其从文件或其它终端接收输入,或者将执行结果输出到文件或其它终端。

GDB 调试器指定的目标程序传递参数,常用的方法有 3 种:

1、启动 GDB 调试器时,可以在指定目标调试程序的同时,使用 --args 选项指定需要传递给该程序的数据。
2、GDB 调试器启动后,可以借助 set args 命令指定目标调试程序启动所需要的数据。
3、除此之外,还可以使用 run 或者 start 启动目标程序时,指定其所需要的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值