【linux系统调试】GDB 工具使用与调试方法大全,看这篇就够了

目录

一. GDB基础调试

1. 启动与断点操作

2. 使用GDB 分析coredump文件

‌2.1 怎样生成coredump 文件

2.2 怎样分析coredump 文件

2.3 为何选择编号0?

2.4 对比其他编号操作

3、常见崩溃类型识别

4、高级调试技巧

5、实战案例解析

5‌.1 场景‌:某嵌入式设备程序偶发崩溃,coredump显示SIGSEGV信号

5.2 代码示例与修复方案

6. 通过 -fsanitize=address 检测内存问题的

‌6.1 示例代码(main.c)

6‌.2 编译命令‌

6.3 运行检测‌

6‌.4 ASan输出解析‌

‌6.5 关键信息解读‌

7. 使用 addr2line 解析 0x7f1c8d8d6a56 地址的完整方法‌

7.1  核心命令格式‌

‌7.2 实战步骤‌

7.3. 常见问题处理‌


‌       GDB 工具是最常见的调试工具,也是平常工作中使用频率最高最广为人知的嵌入式Linux产品软件调试工具。要想使用该工具进行代码调试,首先需要在编译程序时需添加-g选项保留调试信息。这是前提,否则无法进行后续操作。话不多说,直接进入正题。

一. GDB基础调试

1. 启动与断点操作

假如你有一个程序,首先须在编译工具makefile等通过交叉编译工具链编译成一个可执行文件,例如program,编译成功后按照如下操作可以进行gdb工具的基本操作。

  • 加载程序gdb program

  • 设置断点
    gdb program #进入gdb后
    (gdb)
    break main # 在main函数处设断点 
    break file.c:20 # 在指定文件行号设断点
    break func if var=5 # 条件断点
  • 执行控制命令

  1. run:启动程序

  2. next(逐行跳过函数) / step(进入函数)

  3. continue:继续执行至下一断点

  • 信息查看

  1. print var:查看变量值。

  2. backtracebt):显示调用栈。

  3. info locals:查看当前函数局部变量。

2. 使用GDB 分析coredump文件

2.1 怎样生成coredump 文件

  • 目标板解除coredump文件大小限制
    ulimit -c unlimited # 允许生成任意大小的coredump文件
    
    若需永久生效,需修改/etc/security/limits.conf配置文件。
  • 设置coredump文件存储路径与命名规则
    echo "/data/coredump/core-%e-%t-%p" > /proc/sys/kernel/core_pattern
    
    支持的格式参数:
    %e:可执行文件名
    %t:崩溃时间戳
    %p:进程PID

2.2 怎样分析coredump 文件

  • 加载coredump文件
    程序崩溃后会生成coredump
    在开发板使用交叉编译环境对应的GDB工具加载coredump文件:
    arm-linux-gnueabihf-gdb <可执行文件路径> <coredump文件路径>
    
    例如: 以上面设置的路径为例,则在目标板执行如下命令:
    
    arm-linux-gnueabihf-gdb program /data/coredump/coredump文件
  • 查看崩溃调用栈
    ​
    加载coredump后,通过执行bt,可以定位分析崩溃位置。例如:
    
    (gdb) bt full # 显示完整调用栈及局部变量 
    (gdb) f <栈帧编号> # 切换到具体栈帧上下文
    
    ​

   f + 栈帧编号的作用
   f 0frame 0的缩写)表示‌切换到编号为0的栈帧‌,即直接定位到程序崩溃时执行的函数上下 文,此时可查看:

  • 当前函数的局部变量(info locals

  • 函数参数(info args

  • 寄存器状态(info registers

  • 当前活动栈帧编号
    (gdb) bt
    #0 0x080489a0 in process_data () at src/main.c:38 // 当前崩溃位置 
    #1 0x08048b2c in data_processing_thread (arg=0x0) at src/thread.c:56 
    #2 0xf7e3d4c0 in start_thread () from /lib/libpthread.so.0
    通过bt命令查看调用栈时,‌栈帧编号从0开始递增‌:
  1. #0:程序崩溃时正在执行的函数(最内层调用)
  2. #1:调用#0函数的父函数
  3. 依此类推,直到main函数(最高编号)
  • 线程分析
  1. info threads:显示所有线程状态
  2. thread <ID>:切换至指定线程上下文
  3. break file.c:30 thread all:在所有线程设置断点
  • 关键信息检查

    • 指针变量分析‌:
      (gdb) print *ptr # 检查空指针或非法内存访问
    • 内存越界检测‌:
      (gdb) x/10x &array # 查看数组内存分布是否异常

2.3 为何选择编号0?

  • 崩溃现场定位

    当程序触发SIGSEGV等信号时,‌栈帧0是导致崩溃的直接位置‌。例如:

    (gdb) bt 
    #0 0x080489a0 in process_data () at src/main.c:38 // 崩溃点 
    #1 0x08048b2c in data_processing_thread (arg=0x0) at src/thread.c:56

    此时切换到f 0可精确观察process_data()函数内部的变量和代码状态,而非其调用者data_processing_thread

  • <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好多渔鱼好多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值