Linux调试器 - gdb使用指南

目录

一、背景知识

[二、开始使用 gdb](#二、开始使用 gdb)

(一)查看源代码相关指令

(二)程序执行控制指令

(三)断点相关指令

(四)变量操作相关指令

(五)其他常用指令


在Linux系统的软件开发领域,调试程序是确保软件质量和功能正确性的关键环节。 gdb (GNU Debugger)作为一款功能强大且广泛使用的调试工具,为开发者提供了深入剖析程序运行过程、定位问题根源的有效手段。今天,就让我们深入探究 gdb 的使用方法。

一、背景知识

在程序开发中,程序的发布模式主要有两种: debug 模式和 release 模式。 debug 模式下,程序保留了丰富的调试信息,包括变量名、函数名、行号等,这使得开发者能够在调试过程中清晰地了解程序的内部状态,方便查找问题。(内存更大)

而 release 模式则侧重于程序的运行效率,会对代码进行优化处理,并去除大部分调试信息。

readelf -S 文件名 可以以二进制形式访问文件

readelf -S test.o | grep -i debug这条命令的作用是在ELF文件 test.o 中查找与调试信息相关的节区。

具体解释

  • readelf -S test.o :使用 readelf 命令的 -S 选项,用于显示 test.o 文件的节区信息,包括节区的名称、类型、大小、地址等详细内容。

  • | grep -i debug :通过管道符 | 将 readelf -S test.o 的输出结果作为 grep -i debug 的输入, grep 命令用于在输入中搜索包含 debug 字符串的行, -i 选项表示不区分大小写。

执行结果

该命令执行后,会输出 test.o 文件中所有与调试信息相关的节区信息,这些节区通常包含了调试符号、源代码行号等信息,有助于在调试程序时将程序的运行状态与源代码关联起来。

在Linux系统中,使用 gcc/g++ 编译生成的二进制程序,默认采用 release 模式。若要使用 gdb 对程序进行调试,必须在使用 gcc/g++ 编译源代码生成二进制程序时,加上 -g 选项。该选项会使编译器在生成的二进制文件中嵌入调试信息,从而让 gdb 能够识别和利用这些信息进行调试。

二、开始使用 gdb

当我们准备好带有调试信息的二进制程序后,即可启动 gdb 开启调试之旅。启动 gdb 的命令格式为 gdb binFile ,其中 binFile 是待调试的二进制文件名。

若调试完毕想要退出 gdb ,可使用 ctrl + d 组合键,或者直接输入 quit**(q)** 命令。

(一)查看源代码相关指令

**- list / l :**此指令用于显示 binFile 的源代码。它会从上次显示的位置继续往下,每次展示10行代码。通过反复使用该指令,我们能够逐段查看程序的代码逻辑,为后续调试操作奠定基础。

**- list / l 函数名 :**当我们聚焦于特定函数的代码逻辑时,该指令可派上用场。输入函数名后, gdb 会迅速定位并列出该函数的全部源代码内容,方便我们深入分析函数内部实现。

(二)程序执行控制指令

**- r或run :**这是启动程序运行的指令。在完成断点设置等前期调试准备工作后,使用该指令可让程序开始执行,使我们能够观察程序在实际运行过程中的行为表现。

()逐语句执行

**- n或next :单条执行指令。**每执行一次该指令,程序就会执行一条语句,但不会深入函数内部。此指令适用于我们不关心函数内部执行细节,仅需快速推进程序执行流程的场景。

()逐过程执行(理解为跳过一个函数过程)

**- s或step :**与 next 指令不同, step 指令会深入函数调用内部。当我们需要详细了解函数内部的执行逻辑、变量变化以及函数调用关系时,使用该指令可深入到函数内部逐行调试。

(三)断点相关指令

- break(b) 行号 :用于在指定行号处设置断点。当程序执行到设置断点的这一行时,会自动暂停运行,此时我们可以检查程序当前的状态,如变量取值、寄存器状态等信息,以便排查问题。

**- break 函数名 :**在指定函数的开头位置设置断点。这样,当程序运行过程中调用到该函数时,就会立即暂停,方便我们针对该函数进行专项调试,分析函数的输入输出以及内部逻辑是否正确。

**- info break :**用于查看断点信息。当我们在程序中设置了多个断点后,可能难以清晰记住每个断点的具体情况。使用该指令可清晰列出所有已设置断点的详细信息,包括断点编号、所在位置、是否启用等内容,便于我们对断点进行管理。

(四)变量操作相关指令

**- print(p) 表达式 (监视):**该指令用于打印表达式的值。**说白了就是查看变量变化过程,**通过它,我们不仅能够查看变量的当前取值,还能通过表达式变量进行计算、修改变量的值或者调用函数等操作,在调试过程中灵活地探究程序状态。

**- set var :**直接修改变量的值。在调试过程中,当我们想要模拟特定的变量取值情况,以观察程序在不同输入条件下的运行结果时,使用该指令可方便快捷地修改变量值。

(五)其他常用指令

**- finish (跳出函数内部):**执行到当前函数返回,然后暂停下来等待后续命令。当我们进入一个函数内部进行调试,在查看完函数内部相关信息后,若想快速回到函数调用的上层继续调试,使用该指令可直接执行到函数返回,无需逐行单步执行。

**- continue(或c) :**从当前位置开始连续而非单步执行程序。当我们已经仔细检查完程序某个区域的代码,确认该部分代码逻辑无误,想要让程序继续执行下去,以观察后续代码的执行情况时,使用该指令可让程序快速运行,直到遇到下一个断点或程序结束

**- delete breakpoints :**删除所有断点,当我们调试过程中需要清空已设置的所有断点时可使用。

**- delete breakpoints n :**删除序号为 n 的断点,可针对特定断点进行精准删除操作。

**- disable breakpoints :**禁用断点,使已设置的断点暂时失效,而不删除断点信息,后续可重新启用。

**- enable breakpoints :**启用断点,用于恢复被禁用的断点。

**- display(常显示) 变量名 :**跟踪查看一个变量,每次程序停下来时都会显示它的值,便于持续观察变量在程序运行过程中的变化情况。

**- undisplay :**取消对先前设置跟踪的那些变量的跟踪,当我们不再需要关注某些变量时可使用。

**- until X行号 :**使程序执行到指定的 X 行,可快速跳过不需要逐行调试的代码区域。可调制指定行

**- breakrace(或bt) :**查看各级函数调用及参数,帮助我们梳理程序的函数调用栈,了解函数之间的调用关系和传递的参数情况。

**- info (i) locals :**查看当前栈帧局部变量的值,在调试函数内部逻辑时,可用于检查局部变量的状态。

gdb 功能丰富,指令众多,上述介绍的只是其常用指令集。熟练掌握这些指令,能够极大地提升我们在Linux环境下调试程序的效率,帮助我们更加从容地排查和解决程序中出现的各种问题。希望这篇博客能为大家在 gdb 的使用之路上提供有力的指引,让调试工作变得更加得心应手!

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒2 天前
TShark:基础知识
linux
AlfredZhao2 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334663 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪3 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5203 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言