• 正文
  • 相关推荐
申请入驻 产业图谱

printf 格式不匹配导致 Debug 数据错位问题

06/05 09:53
43
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

问题描述

在 ../sys/measure.c 第 260 行通过 dbg_info 打印调试信息:

dbg_info("nv=%d,p=%d,t=%d", temp_data.sensor_data[1].normal_volt, pos, tail);

现象

查看方式 nv pos tail
Debug 观察窗(读内存) ✅ 正确 ✅ 正确 ✅ 正确
printf 打印输出 ✅ 正确 ❌ 始终为 0 ✅ 正确

核心矛盾:变量在内存中的值都是对的,但 printf 打印出来 pos 却是 0。

根因分析

2.1 变量类型

typedef struct {    long long normal_volt;  // 8 字节(64位)    ...} sensor_data_t;int pos;    // 4 字节(32位)int tail;   // 4 字节(32位)

2.2 Debug 观察窗 vs printf 的读取机制

方式 如何读取变量值 受格式符影响?
Debug 观察窗 通过符号表找到变量内存地址,直接按类型读取 ❌ 不经过 varargs
printf 从 varargs 栈上按格式符指定的长度逐字节消费 ✅ 全靠格式符

Debug 观察窗完全绕过了 printf 的变参机制,所以三个值都正确——这恰好证明了变量本身的值没有问题

2.3 printf 参数错位过程

printf("nv=%d,p=%d,t=%d", normal_volt, pos, tail)

调用时,三个参数依次压入 varargs 栈,printf 按 %d(4 字节)逐个消费:

栈布局 (低地址在上,printf 从低地址向高地址依次取 %d):┌──────────────────────┐│ normal_volt 低4字节   │ ← %d#1 → 打印 "nv" (正确)├──────────────────────┤│ normal_volt 高4字节   │ ← %d#2 → 打印 "pos" (恒为 0)├──────────────────────┤│ pos (4字节)          │ ← %d#3 → 打印 "tail" (实际是 pos 的值)├──────────────────────┤│ tail (4字节)          │   未读取└──────────────────────┘
格式符 读到什么 打印显示
%d#1 normal_volt 低 32 位 nv = 正确值(数值小,仅占用低 32 位)
%d#2 normal_volt 高 32 位 pos = 0(高位恒为 0)
%d#3 真正的 pos 值 tail = 正确值(实际是 pos 的值,碰巧相近)

2.4 为什么 nv 和 tail "看起来"正确

nv 正确:normal_volt 数值较小(低 32 位就够表示),高 32 位为 0,低 32 位被 %d#1 读取后自然正确;tail 正确:%d#3 实际读到的是 pos 的真实值,在测试场景下 pos 和 tail 的数值恰好相近或相等,造成"tail 也对"的假象;

实际上三个变量全部错位,只是两个碰巧对上了。

3. 解决方案

// 错误:%d 只能读 4 字节,long long 是 8 字节
dbg_info("nv=%d,p=%d,t=%d", temp_data.sensor_data[1].normal_volt, pos, tail);
// 正确:%lld 读 8 字节,后续参数自动对齐
dbg_info("nv=%lld,p=%d,t=%d", temp_data.sensor_data[1].normal_volt, pos, tail);

4. 经验总结

要点 说明
Debug 观察窗正确 ≠ printf 正确 Debug 窗口读内存地址,printf 走 varargs,两者路径完全不同
部分正确不代表整体正确 即使某些变量值看起来对,也可能是"碰巧",不代表参数对齐正确
格式符必须严格匹配类型 字节数不对 → 所有后续参数全错位
启用编译警告 开启 -Wformat 可让编译器自动检测此类问题

5. 常见类型格式符速查

C 类型 sizeof 格式符
int 4 %d
unsigned int 4 %u
short 2 %hd
long 4/8 %ld
long long 8 %lld
float 4 %f
double 8 %f 或 %lf
char * 4/8 %s
void * 4/8 %p

 

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

公众号:物联网思考;主要记录、分享、思考开发中遇到的技术小细节,涉及嵌入式单片机、C语言、传感器、低功耗物联网等。偶尔也可能是程序员健康、职场潜规则、生活思考、行业讨论。