文章目录
- 🎪 Linux下gdb的使用
- 🚀1.gdb调试准备
- 🚀2.gdb指令集
- 🚀3.gdb指令演示
- ⭐3.1 展示源文件代码
- ⭐3.2 断点与多步调试操作
- ⭐3.3 常用操作指令
🎪 Linux下gdb的使用
GDB 全称“GNU symbolic debugger”,是一个由GNU开源组织发布的,UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具从名称上不难看出,它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。发展至今,GDB 已经迭代了诸多个版本,当下的 GDB 支持调试多种编程语言编写的程序,包括 C、C++、Go、Objective-C、OpenCL、Ada 等。实际场景中,GDB 更常用来调试 C 和 C++ 程序。
🚀1.gdb调试准备
我们的代码编译过后的版本有两种,分别是Debug版(可调试版)和Release版(不可调试版),我们Linux下gcc/g++编译过后的版本默认是Release版本,不妨我们来验证以下:
test.c:
#include <stdio.h>
int addToTop(int top)
{
printf("enter addToTop\n");
int sum = 0;
for(int i = 1; i <= top; i++)
{
sum += i;
}
printf("quit addToTop\n");
return sum;
}
int main()
{
int top = 100;
int result = addToTop(top);
printf("result:%d\n", result);
return 0;
}
Makefile:
test:test.c
gcc test.c -o test -std=c99
.PHONY:clean
clean:
rm -rf test
-std=c99
表示以c99的标准来进行编译
我们的猜想成立,编译器默认生成的可执行文件是不包含调试信息的(也就是不可被调试的)那么我们怎么才能让它变成可调试的呢?我们前几篇博客上讲的gcc基本指令中加上选项-g
表示生成的可执行文件是可被调试的。详情请见:Linux编译器gcc/g++
我们修改Makefile
文件为:
test-release:test.c
gcc test.c -o test-release -std=c99
test-debug:test.c
gcc -g test.c -o test-debug -std=c99
.PHONY:clean
clean:
rm -rf test-release test-debug
然后构建:
test-debug文件比test.release文件要大一些,因为其中包含了调试信息。这时我们再对test-debug进行gdb调试:
🚀2.gdb指令集
Linux调试器gdb的核心工作就是查找问题,下面我们来看一些基本指令:
- l 或 list 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
- l 或 list 函数名:列出某个函数的源代码。
- r 或 run:运行程序至断点处,若没有断点直接运行结束。
- n 或 next:单条执行,不进入函数。
- s 或 step:进入函数调用
- b 或 break 行号:在某一行设置断点
- b 或 break 函数名:在某个函数开头设置断点
- info break :查看断点信息。
- finish:执行到当前函数返回,然后停下来等待命令
- p 变量:打印变量值。
- set var 变量 = 新值:修改变量的值
- c 或 continue:从当前位置开始连续而非单步执行程序,即跳到下一处断点
- delete breakpoints:删除所有断点
- delete breakpoints n:删除序号为n的断点
- disable breakpoints:禁用断点
- enable breakpoints:启用断点
- i 或 info breakpoints:参看当前设置了哪些断点
- display 变量名:跟踪查看一个变量,每次停下来都显示它的值
- undisplay:取消对先前设置的那些变量的跟踪
- until X:跳至X行
- bt 或 breaktrace:查看各级函数调用及参数
- i 或 info locals:查看当前栈帧局部变量的值
- quit:退出gdb
🚀3.gdb指令演示
以我们的test-debug
为例:
⭐3.1 展示源文件代码
- 展示从0/9开始的后10行
指令:l
0/9
- 展示addToTop的源代码
指令:l
addToTop
⭐3.2 断点与多步调试操作
- 对第20行,以及函数addToTop开头添加断点,并显示断点基本信息
指令:b 20
、b addToTop
、info b
- 对第17行添加断点,运行程序展示单步调试
指令:b 17
、r
、n
、s
- 显示循环结束后sum的值,并将其修改为4090
指令:until 11
、p sum
、set var sum = 4090
- 显示断点,删除序号为1的断点,禁用序号位2,3的断点,最后再启用3号断点
指令:i b
、delete breakpoints 1
、disable breakpoints 2
、disable breakpoints 3
、enable breakpoints 3
- 进入函数addToTop查看函数调用与参数以及函数栈帧中局部变量的值
指令:bt
、i locals
⭐3.3 常用操作指令
我们gdb也存在git中三板斧,可以大大简化我们调试的过程分别是 finish、until、continue
-
跳转到目前函数结束:
finish
当我们不小心误入函数的时候,我们可以利用finish
快速结束该函数 -
执行到当前行以下的任意行:
until
对于循环次数过多时,我们可以用until
快速跳出循环 -
断点跳转:
continue
我们可以用continue
来实现断点跳转
此外我们用p 变量
的时候会感觉比较麻烦,每次都要输入命令来查看变量的值,我们可以用dispaly 变量
的方式来长显示变量,这样我们每走一步,都会自动显示display过的变量名
如果想要删除长显示过的变量,用undisplay 变量
即可