一.GDB介绍
A.GDB
1.GNU项目中的调试器
2.能够追踪程序的执行,也能够恢复程序崩溃前的状态
B.GDB的重要性
1.软件不是一次性开发完成的(是软件就有bug,是程序就有问题)
2.调试时软件开发过程中不可或缺的技术
C.GDB的常规应用
1.自定义程序的启动方式(指定影响程序运行的参数)
2.设置条件断点(在条件满足时暂停程序的执行)
3.回溯检查导致程序异常结束的原因
4.动态改变程序执行流(定位问题的辅助方式)
D.GDB的启动方式
1.直接启动--gdb ,gdb test.out ,gdb test.out core,
2.动态链接--gdb test.out pid
示例:对之前的在开发中的辅助工具章提到使用addr2line对程序中出现的错误进行定位,该示例使用gdb调试来完成该操作
运行过程图如图所示
从图中所标记的红线可以知道编译以及gdb的使用过程
1.首先使用gcc生成可调式的结果
2.使用gdb命令开启gdb调试
3.使用file test.out命令关联生成的结果
4.使用run命令生成结果 可以看到在标记5处知道程序出现的错误处
与之前的addr2line命令查找相比,gdb的操作就很快捷与方便
E.使用GDB进行断点调试
1.断电类型
a.软件断点:由非法指令异常实现(软件实现)
b.硬件断点:由硬件特性实现(数量有限)
c.数据断点:由硬件特性实现(数量有限)
F.软件断点的相关操作
a.通过函数名设置断点
1.break func_name
2.tbreak func_name
b.通过文件名行号设置断点
1.break file_name:line_num
2.tbreak file_name:line_num
软件调试的相关操作
代码示例func.c与test.c
#include <stdio.h>
#include <unistd.h>
extern int* g_pointer;
extern void func();
void test_1()
{
printf("test_1() : %p\n", test_1);
}
void test_2()
{
printf("test_2() : %p\n", test_2);
}
void test_3()
{
printf("test_3() : %p\n", test_3);
}
int main(int argc, char *argv[])
{
typedef void(TFunc)();
TFunc* fa[] = {test_1, test_2, test_3};
int i = 0;
printf("main() : begin...\n");
for(i=0; i<argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
for(i=0; i<100; i++)
{
fa[i%3]();
sleep(argc > 1);
}
printf("g_pointer = %p\n", g_pointer);
func();
printf("main() : end...\n");
return 0;
}
#include <stdio.h>
int* g_pointer;
void func()
{
*g_pointer = (int)"D.T.Software";
return;
}
第一次GDB断点调试的过程如下所示
1.首先对上述程序编译并且运行:gcc func.c test.c -o test.out
2./test.out程序会出现段错误--主要是因为在 *g_pointer = (int)"D.T.Software"处对 *g_pointer进行了赋值操作
3.那么现在我们开始使用gdb来定位出错误,在开启gdb调试之前,需要在编译源程序的时候加上-g选项,并将程序的崩溃信息转储的core文件
可以看到
1.先使用gdb test.out以及在 *g_pointe处设置断点之后,在使用了start命令,在main函数的入口处25行生产了断点
2.使用break命令在37行生成断点并且使用info breakpoints查看该断点是否存在
3.继续运行程序发现在37行停住,使用set var命令与next命令对其继续查看
1.使用next命令之后该程跳出循环来到41行
2.使用tbreak命令在43行设置断点,继续运行发现程序正常
3.使用jump命令使其跳至45行,由结果可以得出程序关闭正常,可以猜测程序在43行处有问题
第二次调试过程
1.主要使用tbreak func直接将断点设置在func函数并使用info breakpoints进行查看断点是否设置成功
2.继续运行可以看到提示在func.c:7处提示问题
3.执行return命令发现程序正常结束,可以知道函数在func.c:7出有问题