1、gdb基本功能

文章目录

  • 1、gdb
    • 1.1、运行
      • 1.1.1、程序入参
    • 1.2、断点及观察点
      • 1.2.1、设置断点
      • 1.2.2、禁用、删除断点
      • 1.2.3、观察点
    • 1.3、打印
      • 1.3.1、设定打印参数
      • 1.3.2、打印数据
      • 1.3.3、自动打印
      • 1.3.4、按照地址打印

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 ./
// 有参程序调用
gdb ./ 

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

正常执行后会出现如下界面.
1、gdb基本功能_第1张图片

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

如果程序带有入参,则

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 :
// 在指定文件的指定函数设定断点
b :
// 根据条件设定断点
b : if   例如:x==0

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

1.2.2、禁用、删除断点

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

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

在这里插入图片描述

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

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

在这里插入图片描述

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

使能断点,删除所有断点如下所示.
1、gdb基本功能_第2张图片

删除指定断点示例如下.

在这里插入图片描述

1.2.3、观察点

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

命令 简写形式 说明
info b 利用此方式也可以查看watch信息,也可以使用info watch1、gdb基本功能_第3张图片
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、gdb基本功能_第4张图片

1.3.2、打印数据

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

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

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[]@  打印数组name从idx索引处len长度的数据
p ++a  打印++a的值,此时程序内a的值也将发生变化
p )> 将参数传入函数中,直接调用函数并打印返回值

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

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可以为多个,比如disable display 2 3 4
也可以为一个范围,比如disable display 2-4

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

1.3.4、按照地址打印

命令 简写形式 说明
x/ 按照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形式打印.

你可能感兴趣的:(#,调试,linux,gdb)