1、gdb基本功能


linux下我现在接触到的常用调试工具如下.

  • gbd
  • gdbgui
  • cmake-tools

  gdb是最为通用的,普遍linux会自带gdb工具,使用简单,无额外需求.

  gdbgui需要额外安装,且会占用处理器资源.

  cmake-tools是使用vscode远程ssh设备时在vscode上安装的一个插件,必须用cmake组织管理代码且使用vscode时才可以使用该工具借助于vscode图形化界面进行debug,但相当占用处理器资源.

下面只介绍gdb具体使用方法.

1、gdb

安装方式.

sudo apt-get install gdb

使用方法

// 无参程序调用
gdb ./<exce>
// 有参程序调用
gdb ./<exce> <param>

exce即为代码编译出来的可执行文件.

正常执行后会出现如下界面.
在这里插入图片描述

注意,这个时候程序并没有开始运行.

如果程序带有入参,则

1.1、运行

运行常用相关指令见下表.

命令 简写形式 说明
run r 开始执行程序直到遇到 结束或者遇到断点等待下一个命令;
start st 开始执行程序,在main函数中的第一条语句前停下
continue c 继续程序的运行,直到遇到下一个断点
next n 执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)
step s 执行下一条语句,如果该语句为函数调用,则进入函数执行第一条语句
finish 直接执行完当前函数,返回到调用该函数的位置
quit q 推出gdb调试环境

该部分比较简单,且都比较常用,不再复述.

1.1.1、程序入参

命令 简写形式 说明
set args 设定运行时的参数
show args 查看设定的运行参数

1.2、断点及观察点

gdb支持如下几种断点,且断点可以在程序运行前设置.

  • 普通断点,运行到该处就停止
  • 条件断点,运行到该处后且符合设定条件才停止
  • 临时断点,只生效一次的断点

观察点是运行中设置,而且只能是变量。

1.2.1、设置断点

命令 简写形式 说明
break b 设置断点
break if b if 条件断点,满足if后的条件后停止
tbreak 临时断点,只生效一次

断点有如下几种设置方法.

// 在指定文件的指定行号设定断点
b <file_name>:<file_line>
// 在指定文件的指定函数设定断点
b <file_name>:<fun_name>
// 根据条件设定断点
b <file_name>:<file_line> if <cond>  例如:x==0

临时断点和上述用法一样.

1.2.2、禁用、删除断点

命令 简写形式 说明
info b 显示当前所有断点
d break 删除指定断点
delete d 删除所有断点
disable b 禁用指定断点
enable b 使能制定断点

想要禁用或者删除断点,需要先知道当前共有哪些断点.如下所示.

在这里插入图片描述

从左到右,分别是断点号,类型,使能状态,后面是断点具体位置.

禁用断点示例如下.对应的使能断点不在演示.

在这里插入图片描述

可以看到禁用断点2后,后面的Enb变为了n.代表断点被禁用不生效,但依旧存在.

使能断点,删除所有断点如下所示.
在这里插入图片描述

删除指定断点示例如下.

在这里插入图片描述

1.2.3、观察点

观察点是当变量变化即停止的一种调试手段.

命令 简写形式 说明
info b 利用此方式也可以查看watch信息,也可以使用info watch在这里插入图片描述
watch 只有当被监控变量(表达式)的值发生改变,程序才会停止运行
rwatch 只要程序中出现读取目标变量(表达式)的值的操作,程序就会停止运行
awatch 只要程序中出现读取目标变量(表达式)的值或者改变值的操作,程序就会停止运行

cond可以是变量也可以是表达式.

我只用过变量.以变量说明

struct test{
   
    char name[16];
    uint32_t age;
};
struct test data = {
   0};
struct *p = &test_data;
  • watch data 当data里任意一个数据发生改变即刻停止

  • watch data.age 当data内的age发生改变时停止

  • watch *pwatch data

  • watch p 当p指向内容发生变化时即刻停止

watch设定观察点的方式有两种,默认为1.

  • 硬件观察点
  • 软件观察点

以RK3568举例,实际使用中发现最多只能建立2个硬件观察点,后续在使用watch后,会出现如下提示.

Hardware watchpoint num: Could not insert watchpoint

使用如下指令强制GDB调试器建立软件观察点.

set can-use-hw-watchpoints 0

awatch 和 rwatch 命令只能设置硬件观察点,如果系统不支持或者借助如上命令禁用,则 GDB 调试器会打印如下信息:

Expression cannot be implemented with read/access watchpoint.

备注:软件观察点会导致程序执行效率变低

1.3、打印

1.3.1、设定打印参数

命令 简写形式 说明
set print elements 设定打印长度
show print elements 显示打印长度
set print pretty on 打开换行打印

打印信息过长时,信息显示不全,可以使用set print elements进行设定显示长度.

打印结构体时,默认不换行,使用set print pretty on可以将结构体成员变量换行显示如下所示.

其中红框内的是默认打印方式,下面的是打开换行打印后的显示效果.

在这里插入图片描述

1.3.2、打印数据

命令 简写形式 说明
print/ p 打印数据
ptype <var_name> 查看变量数据类型

简单介绍如下几种简单的使用方式.

int a = 1;
int *p_a = &a;
char name[32] = "name";

p a   打印变量a值
p p_a  打印p_a存储的地址,即a的地址
p *p_a  打印p_a存储地址的所存储的数据
p name  打印name中的字符串值
p name[<idx>]@<len>  打印数组name从idx索引处len长度的数据
p ++a  打印++a的值,此时程序内a的值也将发生变化
p <fun(<param>)> 将参数传入函数中,直接调用函数并打印返回值

如果想要数据按照指定的方式打印,则需要用到参数.参数常用值

fmt 功能
/x 十六进制的形式打印
/d 有符号,十进制形式打印证书
/u 无符号,十进制形式打印证书
/o 八进制打印
/t 二进制打印
/f 浮点数打印
/c 字符打印
/s 字符串打印

如下所示.

p/x a             以十六进制形式打印a变量
p/s name		  以字符串形式打印name数组存储的数据
p/x name[0]@10    以十六进制形式挨个打印name数组从0到len-1索引的数据

如果当前断点在C文件,此时想查看A文件的非局部变量的值,可以通过如下方式.

p <file_name>::<var_name>

可通过下列命令打印变量的类型

ptype <var_name>

1.3.3、自动打印

上述print指令需要用户每次都输入才会执行打印功能.如果想要程序一停止就打印数据可以使用display功能.

命令 简写形式 说明
display
info display 查看自动显示的信息,包含信息编号
disable display 失能自动输出,num代表信息编号
num可以为多个,比如disable display 2 3 4
也可以为一个范围,比如disable display 2-4
enable display 使能自动输出,num代表信息编号
num可以为多个,比如enable display 2 3 4
也可以为一个范围,比如enable display 2-4
delete display d display 删除输出, num代表信息编号,同undisplay <num>
num可以为多个,比如disable display 2 3 4
也可以为一个范围,比如disable display 2-4

display所有用法同print基本一致.

1.3.4、按照地址打印

命令 简写形式 说明
x/<n/f/u> 按照nfu三个参数的配置打印addr出的数据

其中,n、f、u的含义如下.

名称 含义
n 正整数,从addr开始,打印n个长度的数据
f 打印形式,o是8进制,u是无符号10进制,t是二进制,c是字符,s是字符串等,参考print打印形式
u 表示从当前地址往后请求的字节数,即一个长度的单位,默认为4字节,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。

x/16xb: 打印0地址处16个长度单位的数据,每个单位长度为一个字节,共计16个字节数据以16形式打印.

相关推荐

  1. C++-gdb调试常用功能

    2023-12-31 01:30:02       50 阅读
  2. 【<span style='color:red;'>GDB</span>】

    GDB

    2023-12-31 01:30:02      44 阅读
  3. 【Linux】GNU编译器基础-GDB

    2023-12-31 01:30:02       32 阅读
  4. MATLAB初学者入门(1)—— 基础知识和功能介绍

    2023-12-31 01:30:02       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-31 01:30:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-31 01:30:02       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-31 01:30:02       82 阅读
  4. Python语言-面向对象

    2023-12-31 01:30:02       91 阅读

热门阅读

  1. TypeScript 类方法装饰器

    2023-12-31 01:30:02       59 阅读
  2. 什么是redis雪崩

    2023-12-31 01:30:02       56 阅读
  3. ELF Strip

    2023-12-31 01:30:02       43 阅读
  4. RabbitMQ消息队列常见面试题

    2023-12-31 01:30:02       56 阅读
  5. Git 命令

    2023-12-31 01:30:02       45 阅读
  6. 【Linux】修复 Linux 错误 - 地址已在使用中

    2023-12-31 01:30:02       51 阅读
  7. ❀My排序算法学习之选择排序❀

    2023-12-31 01:30:02       53 阅读
  8. CAPL解析DBC文件

    2023-12-31 01:30:02       68 阅读
  9. OpenFeign相关面试题及答案

    2023-12-31 01:30:02       43 阅读
  10. linux安装nginx

    2023-12-31 01:30:02       48 阅读
  11. asset模块在Github的含义

    2023-12-31 01:30:02       56 阅读
  12. 离线服务器中python包的安装

    2023-12-31 01:30:02       50 阅读
  13. webscoket多个客户端同时向一个服务器传输数据

    2023-12-31 01:30:02       58 阅读
  14. PHP8使用PDO对象增删改查MySql数据库

    2023-12-31 01:30:02       56 阅读