当前位置: 首页 > news >正文

变量查看与修改

在使用 GDB 调试程序时,除了控制程序的运行流程以外,最常见的操作就是查看变量的值、查看参数的值,以及在调试过程中临时修改某些变量的值。通过这些命令,可以观察程序运行时的数据变化,从而判断程序逻辑是否符合预期。

1.1 查看函数参数

使用info args(i args)命令可以查看当前函数传入参数的值,包括main函数的argvargc参数。

i args

例如,当前程序停在某个函数内部:

void test(int a, int b) { int sum = a + b; }

在断点处执行:

i args

就可以看见传入的ab变量的值

除了使用i args,也可以直接使用print(p)命令打印某个参数的值:

p a p b

1.2 查看变量

1、查看普通变量

在 GDB 中,可以使用print命令查看变量的值,print可以简写为p

p [变量名]

例如:

p num p ch

默认情况下,p命令会按照变量本身的类型打印结果。如果想按照不同格式查看变量,可以在p后面加格式控制。

常见格式如下:

命令含义
p/d var按十进制打印
p/x var按十六进制打印
p/t var按二进制打印
p/o var按八进制打印
p/c var按字符打印
p/s var按字符串打印

例如:

p/d num p/x num p/t num p/c ch

如果有如下代码:

int num = 65; char ch = 'A';

执行:

p/d num p/x num p/c num

可能得到:

$1 = 65 $2 = 0x41 $3 = 65 'A'

这样可以方便地从不同角度查看变量的值。


2、查看变量类型

如果想查看变量的类型,可以使用如下命令:

ptype [变量名]

ptype显示的信息详细,适合查看结构体、指针、数组等复杂类型。

例如,有如下结构体定义:

struct Student { char name[32]; int age; }; struct Student stu = {"Tom", 18}; struct Student *pstu = &stu;

在 GDB 中可以执行:

ptype stu

可能得到:

type = struct Student { char name[32]; int age; }

这说明变量stu的类型是struct Student,并且 GDB 会把结构体中的成员也显示出来。

如果查看结构体指针变量:

ptype pstu

可能得到:

type = struct Student *

这说明pstu是一个指向struct Student类型的指针。

如果想查看指针指向的对象类型,也可以对指针解引用后再查看:

ptype *pstu

可能得到:

type = struct Student { char name[32]; int age; }

在调试结构体、链表、树、数组指针等复杂数据结构时,ptype非常有用,可以帮助我们快速确认变量的数据类型以及内部成员组成。

whatis命令可以用来查看结构体,类,派生类,普通函数以及类成员函数
ptype命令可以更加详细的查看这些内容,如果显示一个类,ptype会把类的成员变量和成员函数都显示出来i variables`命令用来查看全局变量或者静态变量,比如我们看见一个变量使用,但是不知道该变量是在哪定义的,就可以使用这个命令

ptype /m //只显示成员变量,不显示成员函数 ptype /t //不现实typedef的内容 ptype /o //显示结构体或者类的内存构造以及大小

例如如果我们对结构体占用内存大小进行优化,可以使用ptype命令对结构体进行查看,查看他对内存空间的利用率

(gdb) ptype /o node /* offset | size */ type = struct NODE { /* 0 | 4 */ int ID; /* 4 | 4 */ int age; /* 8 | 1 */ char gender; /* XXX 7-byte hole */ /* 16 | 8 */ NODE *next; /* 24 | 4 */ int test; /* 28 | 1 */ char c; /* XXX 3-byte padding */ /* total size (bytes): 32 */ }

可以看见对于上面的结构体,所有成员直接加起来才22个字节,但是使用不合理的排布之后,会用32个字节才能存下,调整结构体之后,可以优化内存布局到24个字节

(gdb) ptype /o node2 /* offset | size */ type = struct NODE2 { /* 0 | 4 */ int ID; /* 4 | 4 */ int age; /* 8 | 8 */ NODE *next; /* 16 | 4 */ int test; /* 20 | 1 */ char gender; /* 21 | 1 */ char c; /* XXX 2-byte padding */ /* total size (bytes): 24 */ }

i variables + 变量的正则表达可以查看对应的变量是在哪个文件中定义的。

1.3 查看数组、字符串、结构体和指针

1、查看数组

对于普通数组,可以直接打印数组名:

p arr

也可以查看数组中的某一个元素:

p arr[0] p arr[1]

如果是指针指向一段连续内存,可以使用下面的方式查看多个元素:

p *ptr@10

这表示从ptr指向的位置开始,连续打印 10 个元素。

例如:

int arr[5] = {1, 2, 3, 4, 5}; int *ptr = arr;

在 GDB 中执行:

p *ptr@5

可能输出:

$1 = {1, 2, 3, 4, 5}

2、查看字符串

直接通过p [字符串变量名称]命令就可以显示查看字符串。

查看字符串变量的时候,如果字符串为100个字符串,填充了10个字符之后,后面的字符全为0这时候显示字符串的时候就不是很好看,使用以下命令设置输出显示格式

set print null-stop

例子如下,在没有设置显示格式之前,可以看见,打印的test.name会因为\0的问题,出现显示问题。

设置字符串显示格式之后

可以看见,对应的字符串在应该结束的地方断开。


3、查看结构体变量

如果是结构体变量,可以直接打印:

p student

如果只想查看结构体中的某个成员,可以使用:

p student.name p student.age

例如:

struct Student { char name[32]; int age; }; struct Student stu = {"Tom", 18};

在 GDB 中可以执行:

p stu p stu.name p stu.age

使用以下命令可以使得,在直接打印结构体变量的时候,可以让结构体的每一个成员独占一行

set print pretty


4、查看指针

如果变量是结构体指针,需要使用->访问成员:

p node->data p node->next

如果想查看指针指向的整个结构体内容,可以使用:

p *node

这在调试链表、树、队列等数据结构时非常常用。

1.4 查看局部变量

使用info locals(i locals)命令可以查看当前函数中的局部变量。

i locals

例如:

void test(int a, int b) { int sum = a + b; int count = 100; }

当程序停在test函数内部时,执行:

i locals

会把当前函数中的所有局部变量的值打印出来:

sum = 30 count = 100

1.5 表达式与函数调用

在GDB中,p命令不仅可以打印普通变量,也可以计算表达式的值,甚至可以调用程序中的函数或库函数。

例如,可以使用sizeof查看类型或变量所占的字节数:

p sizeof(int) p sizeof(long) p sizeof(char *) p sizeof(变量名)

如果程序中有如下变量:

int num = 10; char name[32] = "hello";

在 GDB 中执行:

p sizeof(num) p sizeof(name)

可能得到:

$1 = 4 $2 = 32

其中,sizeof(num)表示变量num所占的字节数,sizeof(name)表示整个数组name所占的字节数。

除了sizeof,也可以在 GDB 中调用一些函数,例如strlen

p strlen(name)

如果name中保存的是字符串"hello",执行结果可能是:

$3 = 5

这表示字符串的有效长度为 5,不包含字符串结尾的'\0'

1.6 修改变量

在 GDB 调试过程中,不仅可以查看变量的值,也可以临时修改变量的值。修改变量常用于验证程序逻辑,例如让程序进入某个特定分支、提前结束循环,或者人为设置某些异常条件,从而观察程序后续的执行情况。

例如,在调试for循环时,可以临时修改循环变量的值,让循环提前结束;在调试if判断时,也可以修改条件变量的值,让程序进入不同的分支。

在实际调试中,比较常用的方式是直接使用p命令执行赋值表达式:

p [arg]=[vaule]
http://www.cnnetsun.cn/news/3211929.html

相关文章:

  • 2026项目管理系统横向盘点:从工具到平台的进化之路
  • SpringBoot + Nacos/Apollo
  • 别让安全预算打水漂:用“滑动标尺模型”校准企业安全投资优先级
  • 动态深度学习的锂离子电池故障检测
  • 不止于省钱,更是零碳新基建:低碳园区“光储充”微电网正在改写规则
  • 致所有还在做梦的人(重构笔记版)
  • 【python零基础教程第10讲】Python 闭包与装饰器
  • 一篇看懂 Linux 终端常用命令:从零掌握增删改查与权限管理
  • 加了Query改写,准确率从71%提到89%
  • MongoDB-集合(表)关联查询
  • 【OpenHarmony/HarmonyOs 】化学学习 App 收藏夹功能实践:AppStorage 本地持久化与响应式刷新
  • 音视频编解码:VP8 / VP9 / H.264 / Opus
  • 2026降AIGC革命:AI率92%暴降至5%!实测10款AI智能降重工具!10款工具深度解析!
  • 3分钟搞定网易云插件安装:BetterNCM-Installer终极解决方案
  • spring通过方法注入,针对多实例的Bean
  • 2026年7月探寻四川信誉优良的GEO优化运营商
  • AutoJS6 + Shizuku 实战:淘金币自动签到与任务脚本
  • 如何一次性解决所有Visual C++运行库问题:终极AIO安装指南
  • Typeahead 2.0 智能搜索体验升级实战
  • 阿里面试:如果Agent 挂100个 Skill ,如何提升召回率、准确度、F1综合值?尼恩 《Skills调优圣经》,来一次 泰山压顶 式的 降维打击
  • rust 学习 闭包
  • 第4章:Linux系统重点复习
  • AI 看不懂老项目?先用“项目说明书 + 目录树”把上下文交给它
  • [特殊字符]《京东宙斯迁移公告解读:老接口 360buy.ware.get→ jingdong.ware.read.get平滑切换(附Python源码)》
  • 从零搭建工业物联网监控大屏:Node-RED + 有人云 零代码方案
  • HRD进化论04讲:战略解码
  • PostgreSQL高级特性应用
  • PyTorch DDP 多机多卡配置:2节点8卡集群部署与通信瓶颈分析
  • Models-学习指南_小白版
  • Mermaid终极指南:用代码快速创建专业图表,彻底告别文档滞后问题