新闻详情

新闻详情

首页 / 资讯中心 / 详情

排查了一周的灵异 Bug,真相是一个不起眼的类型转换

发布时间:2026/9/6 3:52:54来源:尧图网络
排查了一周的灵异 Bug,真相是一个不起眼的类型转换
大家好我是仲一。最近在排查一个嵌入式 Linux 项目有个模块跑着跑着局部变量会莫名其妙被改掉。反复定位下来根因很小——一个unsigned int的地址被当成unsigned long long *传进了函数。用几段代码还原一下现场。第一段代码#include stdio.h#define CONFIG_SIMPLE_SYS_BOOTARGS mem%luM consolettyS0,115200 root/dev/mtdblock%d rootfstypesquashfsvoid test(unsigned long long *size){unsigned long long memsize456789;*sizememsize;}intmain(){unsigned int var272;int var214;char var3[256]{0};printf( var2:%d\n,var2);test((var));printf( var2:%d\n,var2);sprintf(var3, CONFIG_SIMPLE_SYS_BOOTARGS, var, var2);printf( var2:%d\n,var2);return0;}问题出在test((var))。var只占了 4 字节test期望的是一个unsigned long long *——它要写 8 字节。编译器会报个 warning但程序照常运行test往var的地址一口气写 8 字节多出来的 4 字节正好踩到相邻的var2。实际项目里的写法更隐蔽一点#include stdio.h#define CONFIG_SIMPLE_SYS_BOOTARGS mem%luM consolettyS0,115200 root/dev/mtdblock%d rootfstypesquashfsvoid boot_getMemSize(unsigned long long *size){unsigned long long memsize419430400;*sizememsize;}intmain(){unsigned int memSize272;int partIndex14;char tempBuf[256]{0};printf( partIndex:%d\n,partIndex);boot_getMemSize((memSize));printf( partIndex:%d\n,partIndex);sprintf(tempBuf, CONFIG_SIMPLE_SYS_BOOTARGS, memSize, partIndex);printf( tempBuf:%s\n,tempBuf);printf( partIndex:%d\n,partIndex);return0;}这种问题常见的原因就两个要么一开始就把unsigned int当unsigned long long传了要么函数接口升级了类型调用方没跟上。那能不能不动变量类型只改函数签名来绕过有人试过这么写#include stdio.h#define CONFIG_SIMPLE_SYS_BOOTARGS mem%luM consolettyS0,115200 root/dev/mtdblock%d rootfstypesquashfsvoid boot_getMemSize(unsigned long long **size){static unsigned long long memsize419430400;*sizememsize;}intmain(){unsigned int *memSize;int partIndex14;char tempBuf[256]{0};printf([] partIndex1:%d\n,partIndex);boot_getMemSize(memSize);printf([] partIndex2:%d,memSize%lu\n,partIndex, *memSize);sprintf(tempBuf, CONFIG_SIMPLE_SYS_BOOTARGS, *memSize, partIndex);printf([] tempBuf:%s\n,tempBuf);printf([] partIndex3:%d\n,partIndex);return0;}绕了个弯但引入了static变量多线程或函数重入就炸了不推荐。反汇编看一下回到第一种情况看反汇编就一清二楚了。000000000040063cmain: intmain(){40063c: a9ae7bfd stp x29, x30,[sp,#-288]!400640: 910003fd mov x29, sp unsigned int var10;400644:52800140mov w0,#0x0a400648: b9011ba0 str w0,[x29,#280]int var25;40064c: 528000a0 mov w0,#0x5400650: b9011fa0 str w0,[x29,#284]...test((var));400678: 910463a0addx0, x29,#0x11840067c: 97ffffe5 bl400610test...var在x29280var2在x29284紧挨着。test的x0指向了var。再看test的函数体void test(unsigned long long *var){... *vartempVar;400624: f94007e0 ldr x0,[sp,#8]400628: f9400fe1 ldr x1,[sp,#24]40062c: f9000001 str x1,[x0]}str x1, [x0]一条指令写 8 字节。x0指向的是var4 字节后 4 字节直接盖到var2上去了。总结根因一句话函数参数类型和实参类型不匹配。8 字节写入 4 字节的目标多出来的字节肯定踩到旁边的变量。平时写代码编译器的-Wpointer-sign和-Wformat开关建议打开。如果有强制类型转换特别留心两边的内存大小。常见踩坑场景接口升级改了参数类型调用方漏了没改用了void*做通用参数传参时类型搞错头文件更新了其他模块没重新编译遇到局部变量鬼畜改值的先看看是不是指针类型大小不匹配。end往期推荐嵌入式Linux必读经典书籍嵌入式学习路线推荐一位读者逻辑清晰的提问机械转行嵌入式成功上岸一位音视频方向读者秋招上岸的经历
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

ANSYS Polyflow Workbench实战指南:聚合物挤出与吹塑仿真要点解析 2026/9/6 4:28:58

ANSYS Polyflow Workbench实战指南:聚合物挤出与吹塑仿真要点解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
软考中级冲刺阶段,做题总错四部步 2026/9/6 4:28:58

软考中级冲刺阶段,做题总错四部步

很多人备考软考中级系统集成项目管理工程师,会有一种很挫败的感觉:老师讲的时候都懂,自己做题时又错。这不一定说明你没学会,而是说明你还停在“听懂层”,没有进入“会判断层”。软考中级系统集成的基础知识题&#xf…

阅读更多 →
县城外卖平台商家结算周期怎么定?先把完成单、退款窗口和提现日拆开 2026/9/6 4:28:58

县城外卖平台商家结算周期怎么定?先把完成单、退款窗口和提现日拆开

县城外卖平台设置商家结算周期时,建议把三个时间点分开:订单完成是收入进入待结算的起点,退款或售后窗口决定何时可结算,提现日则是商家收到款项的时间。先按订单状态形成待结算清单,再按退款、配送费和平台服务费拆分…

阅读更多 →
用本地网关统一Codex与Claude接入:协议转换实践 2026/9/6 4:28:58

用本地网关统一Codex与Claude接入:协议转换实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
智能体开发实战:62个Skill协同构建电商客服助手 2026/9/6 4:28:58

智能体开发实战:62个Skill协同构建电商客服助手

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
语音+大模型指挥机器人:LLM Agent × ROS2 端到端实战 2026/9/6 4:25:58

语音+大模型指挥机器人:LLM Agent × ROS2 端到端实战

语音大模型指挥机器人:LLM Agent ROS2 端到端实战 你对着麦克风说"左转九十度",Gazebo 里的小车真的转了 90; 你问"前面有障碍物吗",机器人用激光雷达的真实数据开口回答你。 全程离线,没有一个请…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞