一.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出有问题