GDB简介

来源:互联网 发布:淘宝客服是干嘛的 编辑:程序博客网 时间:2024/05/10 20:02

1 GDB简介

什么是GDB?
GNU项目中的调试器(gnu debuger),能够跟踪程序的执行,也能恢复程序崩溃前的状态。

为什么需要GDB?
软件不是一次性开发完成的(是软件就有bug,是程序就有问题),调试是软件开发过程中不可或缺的技术(调试工具很重要)。

GDB的常规应用

  • 自定义程序的启动方式(指定影响程序运行的参数)
  • 设置条件断点(在条件满足时暂停程序的执行)
  • 回溯检查导致程序异常结束的原因(Core Dump)
  • 动态改变程序执行流(定位问题的辅助方式)
      

GDB和addr2line工具的本质区别
addr2line是静态分析工具,关注的是程序文件;GDB是动态分析工具,关注的是进程。

2 GDB的启动方式

直接启动

  • gdb
  • gdb test.out
  • gdb test.out core

动态连接

  • gdb test.out pid

GDB应用举例

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;}

func.c

#include <stdio.h>int* g_pointer;void func(){    *g_pointer = (int)"D.T.Software";    return;}

采用如下方式进行编译

gcc -g test.c func.c -o test.out

直接运行test.out会出现段错误,下面使用GDB进行bug定位:

方式一:
为了在发生段错误时生成core文件,需要执行如下命令:
ulimit -c unlimited
接下来执行应用程序:
./test.out
使用GDB进行调试:
gdb ./test.out core

方式二:
gdb 启动
file test.out 载入目标程序
set args lmeon 设置命令行参数
run 执行目标程序

如果需要暂停程序执行,ctrl+c 即可。输入continue 或者按下enter键即可恢复程序执行。

这里写图片描述

方式三:

这里写图片描述

可以使用ps aux 获取已经运行进程的pid,打开gdb时需要root权限,可以使用sudo命令。

3 使用GDB进行断点调试

3.1 断点类型

软件断点:由非法指令实现(软件实现)

硬件断点:由硬件特性实现(数量有限)

数据断点:由硬件特性实现(数量有限)

3.2 软件断点的相关操作

通过函数名设置断点

break func_name [ if var == name ](永久性断点)

tbreak func_name [ if var == name ](临时断点,只会暂停一次,条件断点只能跟踪函数参数的值,而不能跟踪函数内的局部变量,只有运行到当前函数后打断点才可以跟踪局部变量的值)
  

通过文件名行号设置断点

break file_name:line_num [ if var = name ]

break file_name:line_num [ if var = name ]
  

软件断点的相关操作

这里写图片描述

调试时的常用操作

这里写图片描述

run直接执行可执行程序,start在执行可执行程序后立即暂停(停在main函数的第一行)。

3.3 硬件断点应用

  • 当代码只读存储器(Flash)时,只能通过断点调试。
  • 硬件断点调试需要硬件支持,数量有限。
  • GDB中通过hbreak命令支持硬件断点
  • hbreak与break的使用方式完全一样
  • 可以通过show can-use-hw-watchpoint查看支持的硬件断点数
      

GDB小结

  • GDB时GNU项目中的调试器,能够跟踪或改变程序的执行
  • GDB能够根据Core Dump回溯检查导致程序异常结束的原因
  • GDB同时支持软件断点、硬件断点和数据断点
  • GDB是嵌入式开发中必须掌握的重要工具

3.4 数据断点

数据断点

  • GDB中支持数据断点的设置
  • watch命令用于监视变量是否改变(本质上为硬件断点,即硬件支持的断点)
  • watch命令的用法:watch var_name

4 GDB中的内存查看

GDB中可以检查任意内存区域中的数据。

命令语法: x /Nuf expression

  • N-需要打印的单元数
  • u-每个单元格的大小
  • f-数据打印的格式

示例:x /4bx 0x804a024

x命令中参数u对应的单位

这里写图片描述

GDB中的打印格式
这里写图片描述

示例:判断系统大小端
这里写图片描述

编程实验:变量断点和内存查看

#include <stdio.h>#include <pthread.h>#include <unistd.h>int g_var = 0;void* thread_func(void* args){    sleep(5);    g_var = 1;}int main(){    int i = 0;    pthread_t tid = 0;    pthread_create(&tid, NULL, thread_func, NULL);    for(i=0; i<10; i++)    {        printf("g_var = %d\n", g_var);        sleep(1);    }}

注意:编译的使用使用的命令为gcc -g -pthread watch.c