目录
????????GDB(GNU Debugger)是一个功能强大的开源调试器,它用于调试C、C++等程序,在Linux环境下软件开发的过程中,调试是一个至关重要的环节。无论是在开发新的软件还是维护现有的代码,都难免会遇到各种各样的bug和问题,所有学会使用调试器是非常有必要的。
????????程序的发布方式有两种,Debug模式和release模式
为什么要存在两种?
????????Debug模式通常用于开发阶段,它会保留所有的调试信息,包括符号表、断点和日志,以便开发人员可以轻松地调试和定位问题。此外,Debug模式通常会关闭一些优化选项,以便在开发过程中能够更快地构建和运行程序。这样可以加快开发人员的迭代速度,提高开发效率
????????release模式则用于最终发布产品的版本。它会启用各种优化选项,以提高程序的性能和减小体积。同时,release模式会删除所有的调试信息,从而减小程序的体积和保护源代码不被泄露。这样可以确保最终发布的产品具有更好的性能和安全性
Linux gcc/g++编译程序默认是什么模式?
在默认的情况下,Linux gcc/g++出来的二进制程序,默认是release模式
gcc的默认行为:
如何以Debug模式下发布?
在使用gcc/g++
编译时加上 -g选项 比如:
gcc -o mytest test.c -g
查看可执行程序添加的调试信息:
readelf
指令(elf为可执行程序的格式)比如:
readelf -S mytest | grep -i debug
?结果如下:
在此之前需要先确保Linux机器上是否安装gdb,安装指令:
sudo yum install -y gdb
进入调试:
gdb binFile//binFile也就是编译后产生的可执行程序
Linux版本基本调试功能:
运行起来才能调试(r)
调试时可以看到代码(l)
打断点/删除断点(b 断点位置、d 断点编号)
关闭/开启断点(enable、disable)
局部调试(finish、until、c)
看到/取消 局部变量的内容和地址(display、undisplay)
看到调用栈(bt)
单步执行(s)
逐过程执行(n)
打印变量值(p)
在调试过程中修改变量的值(set var)
?后续示例使用的代码:
#include<stdio.h>
int Sum (int n)
{
int i = 1;
int sum = 0;
for(; i <= n; i++)
{
sum +=i;
}
return sum;
}
int main()
{
printf("hello world!\n");
//……
int ret = Sum(100);
printf("%d\n",ret);
return 0;
}
Linux调试器gdb:
l 行号:显示指定行之后的代码(gdb自动记录最近一条指令)
点击回车可以继续查看后边的代码
打断点:在指定位置打断点
b 行号
b 文件名:行号
b 函数名
查看断点:info b
关闭断点:disable 断点编号
此时编号为1的断点已被关闭,keep后边属性显示n(no)
开启断点:enable 断点编号
r开始调试:直接跳到断点位置
直接跳转到了第一个断点位置
逐语句 s(可进入函数)
逐过程 n(逐行执行)
quit:退出gdb
display 变量的内容和地址:跟踪查看一个变量,每次停下来都显示它的值
每次逐语句执行时都输出了sum和i的值
undisplay 编号:取消常显示变量的内容和地址
重新开始调试,r直接执行到第一个断点位置,c执行到下个断点
finish:执行完当前函数并返回,然后停下来
我们调试进入Sum函数,可以通过finish指令检查Sum函数,finish指令让Sum函数立即执行完毕,并返回返回值
breaktrace(或bt):查看各级函数调用及参数
until 行号:跳至对应行(范围执行)
重新调试进入Sum函数的循环
我们发现代码一直卡在9行和7行,我们又不想立即执完函数,就要求立即执行完循环,这时就可以使用until
直接跳到11行,这样就可以直接执行完循环?
p 变量:打印变量值。
(gdb) p sum
$2 = 5050
set var 变量:修改变量的值(不用修改代码,测试其他分支)
比如我们在测试if语句分支时
if(flag==1)...
else ...
如果代码中以及规定flag值为1,但是又不想重新打开代码进行修改,这时就可以使用set var
比如:
set var flag=0
就可以直接修改flag的值来测试另一条分支
? ? ? ? 在软件开发的过程中,无论是初学者还是经验丰富的开发人员,都会遇到各种各样的bug和问题,学会使用gdb,可以极大地提高代码调试的效率和准确性,好了以上便是本文的全部内容,感谢阅读!