目录
一:gdb简介
二:示例代码
三:使用
1.启动gdb
2.各种指令
<1>: 查看源代码
<2>:设置断点
<3>:查看断点信息
<4>:删除断点
<5>: run
<6>:逐过程调试
<7>:逐语句调试
<8>:查看变量值
<9>:跳转行号
四:总结
一:gdb简介
GDB 全称“GNUsymbolic debugger”,是 Linux 下常用的程序调试器。发展至今,GDB 已经迭代了诸多个版本,当下的 GDB 支持调试多种编程语言编写的程序,包括 C、C++、Go 等等。实际场景中,GDB 更常用来调试 C 和 C++ 程序。一般来说,GDB主要帮助我们完成以下四个方面的功能: 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。 在某个指定的地方或条件下暂停程序。 当程序被停住时,可以检查此时你的程序中所发生的事。 在程序执行过程中修改程序中的变量或条件,将一个bug产生的影响修正从而测试其他bug。
二:示例代码
code.c 文件内容为:
#include<stdio.h>
int ADDToTop(int num)
{
int result = 0;
int i = 0;
for(i = 1; i <= num; i++)
{
result += i;
}
return result;
}
int main()
{
int num = 10;
int sum = 0;
sum = ADDToTop(num);
printf("sum: %d\n",sum);
return 0;
}
makefile 文件内容为:
mycode:code.c
gcc -o $@ $^ -g
.PHONY:clean
clean:
rm -f mycode
我们知道程序的发布形式,有两种,一种为 debug 模式,另一种为 release 模式。一般情况下,编译指令为: gcc code.c -o test ,要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项。不加就是默认为 release 版本。
编译为 debug 版本的指令为:
gcc code.c -o code.debug -g -std=c99
debug版本需要一些调试信息,占用的内存更大,所以我们可以通过占用内存的大小,判断Linux gcc/g++出来的二进制程序,默认是哪一种模式?
通过上述示例,我们可以看出,Linux gcc/g++出来的二进制程序,默认是release模式。
-std = c99 ,c99 是C语言的一个标准,该标准规定了可以在循环控制条件里面定义变量,(eg:for(int i = 0; i < 10; i++)。如果没有使用,则可能会导致:
三:使用
1.启动gdb
启动 gdb 的指令为 [gdb + 文件的名称] 示例:
gdb mycode
运行效果为:
此时,需要我们切换为 root 用户,安装 gdb ,如下图所示:
此时,我们再切回普通用户,进行启动 gdb 的工作:
如果出现上述界面,则说明已经进入 gdb 调试,接下来可以开始使用各种指令进行调试。
2.各种指令
在进行各种调试指令之前,我们需要首先知道退出调试的指令:
ctrl + d 或 quit 调试命令
<1>: 查看源代码
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
<2>:设置断点
break(b) 行号:在某一行设置断点
我们此处在以 #include<stdio.h> 为第一行的第16行打上断点:
break 函数名:在某个函数开头设置断点
在 main 函数,和 ADDToTop函数开头打断点
<3>:查看断点信息
info break :查看断点信息
我们查看在 <2> 第16行所打的断点:
Num --- 编号 Type --- 种类 Address --- 断点在内存中的位置 What --- 断点在程序中的位置
查看 <2> 中指定函数名打断点:
<4>:删除断点
delete breakpoints n:删除序号为n的断点disable breakpoints:禁用断点enable breakpoints:启用断点
n --- 表示该断点不可用,y --- 表示该断点可用
如果想把已经变为 n 的改变为 y ,则需要执行:enable b 3 命令,示例:
<5>: run
run(或r):从开始连续而非单步执行程序如果有断点,则执行到断点处停止,如果没有断点,则执行到结束。
<6>:逐过程调试
n 或 next:单条执行。一步步执行,但不会进入函数内部
清空原来的所有断点,在第16行打上断点,按下 r 运行键,程序会在断点处停下,此时输入 n,观察现象:
程序直接执行完了 ADDToTop 函数内部的全部内容。
<7>:逐语句调试
s或step:进入函数调用,遇到函数时,会进入函数内调试
保持第16行的断点,按下 r 执行到断点处停止,此时在按下 s ,观察现象:
我们发现逐语句调试过程中,进入了 ADDToTop 函数内部,并且一步一步往下执行。
<8>:查看变量值
p 变量:打印变量值。
可以用于查看循环执行到某一步的时候,查看某个/某些变量的值,如下图所示:
<9>:跳转行号
until X行号:跳至X行
当我们进入一个函数后,可能会存在需要循环很多次的场景,此时,我们可以通过 until 行号 跳转到指定行数,示例如下:
四:总结
- list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
- list/l 函数名:列出某个函数的源代码。
- r或run:运行程序。
- n 或 next:单条执行。
- s或step:进入函数调用
- break(b) 行号:在某一行设置断点
- break 函数名:在某个函数开头设置断点
- info break :查看断点信息。
- finish:执行到当前函数返回,然后挺下来等待命令
- print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
- p 变量:打印变量值。
- set var:修改变量的值
- continue(或c):从当前位置开始连续而非单步执行程序
- run(或r):从开始连续而非单步执行程序
- delete breakpoints:删除所有断点
- delete breakpoints n:删除序号为n的断点
- disable breakpoints:禁用断点
- enable breakpoints:启用断点
- info(或i) breakpoints:参看当前设置了哪些断点
- display 变量名:跟踪查看一个变量,每次停下来都显示它的值
- undisplay:取消对先前设置的那些变量的跟踪
- until X行号:跳至X行
- breaktrace(或bt):查看各级函数调用及参数
- info(i) locals:查看当前栈帧局部变量的值
- quit:退出gdb