0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RT-Smart开发笔记:int类型数值溢出造成的奇怪问题的分析与排查记录

冬至子 来源:张世争 作者:张世争 2023-10-31 16:16 次阅读

前言

最近在调试 RT-Smart 上的用户态 mq(消息队列)时,遇到一个奇怪的问题,这个例程打印了一下获取的时间,就可以正常的工作(超时退出),否则,就一直卡住(无法超时)

虽然没有认真的阅读用户态 mq 的具体实现代码,大概能了解到底层对接了 IPC 消息队列,如果一直卡住,可能的原因是超时时间参数没有正确传递下?

排查思路

当前未采用 qemu 调试,直接使用板子验证,所以就手动增加了一些 LOG,用户态应用与 内核态的应用,很快定位到是 内核代码 softwarekernelcomponentslibccompilerscommonctime.c 中的函数 rt_timespec_to_tick 返回值异常导致的

1.jpg

开启log 打印一下时间,就可以【正常】退出

1.jpg

不开启 log,发现卡住了,也就是 ipc 一直没有超时

1.jpg

继续排查

发现 tick 计算的有问题,异常的 tick,也就是 IPC timeout 非常大

1.jpg

1.jpg

找到根源:int 型乘法计算溢出
tick = second * RT_TICK_PER_SECOND + nsecond * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND;,这里 nsecond 定义为 int 类型,int 是 32位,所以当 nsecond 较大时,再乘上 RT_TICK_PER_SECOND, 也就是 1000,由于32位有符号整数溢出,变为了【负值】。

而此时 second 比较小,造成 tick 为一个 负值,但是 timeout 是无符号的,所以把一个负值当成无符号数,就是一个比较大的数值

1.jpg

解决方法

第一种,把 nsecond 定义为 int64_t 类型,也就是 long long 类型,这样计算时,会按照 64位计算,不会溢出

第二种:把 tick = second * RT_TICK_PER_SECOND + nsecond * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND; 改为 tick = second * RT_TICK_PER_SECOND + nsecond / (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);

小结

这问题,如果粗心一点,可能会直接【放过】,比如加了 LOG 打印发现没有问题,但是细节决定成败,有些 BUG 可能出现的方式很奇特,这就是测试代码需要有一定的覆盖性,各个场景下都需要验证,比如 Debug 版本、 Release 版本都测试一下,看看现象是否一致。

经过了解 int 溢出,也发现了一些基础性的知识点,如 32位与64位 CPU 下, long long 类型都是 8字节,如果使用 long 类型定义 nsecond,在 32位平台上,是 4字节,依旧是异常有问题

修复问题后,再次验证,发现定时比较的准确了,偏差很小,比如 20秒,20000 个 tick,而不是 19001 个 tick

1.jpg

修复后,再次运行的效果,此时 tick = 19994,与 20秒比较匹配

msh /kernel>./mq_test
msh /kernel>31111111111111111111111111111
msg_queue is 3
main : enter
sys_mq_timedreceive : 5974 1514764824-963161303
tp : 1676378 - 1514764804
tm_spec : 1676378 - 1514764824
rt_timespec_to_tick : line - 730, second : 19, nsecond : 994459929
rt_timespec_to_tick : tick = 19994
mq_timedreceive : tick = 19994
mq_receive()

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10550

    浏览量

    207691
  • IPC
    IPC
    +关注

    关注

    3

    文章

    321

    浏览量

    51456
  • 调试器
    +关注

    关注

    1

    文章

    294

    浏览量

    23481
  • RT-Thread
    +关注

    关注

    31

    文章

    1199

    浏览量

    39060
  • qemu
    +关注

    关注

    0

    文章

    54

    浏览量

    5258
收藏 人收藏

    评论

    相关推荐

    RT-Smart的资料合集

    的,因此能够很好地缓解外部碎片的问题。下图表达了伙伴系统的基本思想,基于伙伴块进行分裂与合并。3、使用GDB对RT-Smart进行代码调试的方法在开发的过程中,有时没有现成的图形化开发环境,想要进行调试
    发表于 03-22 15:06

    rt-smart中断阻塞问题是怎么引起的

    rt-smart 中断阻塞问题如何解决?该问题是怎么引起的?为了测试rt-smart的实时性,测试了一下中断的稳定性。用systick的1ms中断做测试源。平时都正常的,但是发现打印时,波形老是抖动
    发表于 03-25 09:56

    [IMX6ULL]RT-Smart系统下的软件移植笔记推荐

    1、RT-Smart系统下的LwIP移植关于 i.MX 6ULL 的启动方式,已经老生常谈了。关于启动过程的分析,网上能搜到一堆原理讲解,不过不推荐把那个解释当作最佳答案,建议还是自行从手册入手关于
    发表于 03-25 16:25

    D1哪吒开发rt-smart内核固件的烧写与运行步骤

    打包,打包后镜像,可以烧写到 哪吒开发板 NandFlash中运行默认 Tina Linux 打包后是 Linux 系统镜像,如果想替换为 rt-smart,最简单的方式就是使用 rt-smart 替换
    发表于 06-17 11:06

    开机体验rt-smart:webserver网关

    软件代码交叉编译成目标系统平台可以运行的库或二进制文件,作为 rt-smart 的一个用户 APP,并在 ART-Pi Smart 开发板上运行。用户也可以根据 文档下面的章节 “用户 APP
    发表于 06-30 11:17

    D1S使用rt-smart驱动OLED

    D1S使用rt-smart驱动OLED前言本次使用RT-Smart的IIC驱动OLED屏幕,进行基本的字符串显示,在使用的过程中遇到一些问题,在这里做记录分享,本次以熟悉RT-Smart
    发表于 03-25 11:06

    D1S使用rt-smart驱动OLED

    ,进行基本的字符串显示,在使用的过程中遇到一些问题,在这里做记录分享,本次以熟悉RT-Smart使用为主。过程本次直接开始添加离线包,环境搭建请参考上一篇文章:https://bbs.aw-ol.com
    发表于 04-03 11:27

    rt-smart中的imx6ull用户态点灯

    rt-thread的rt-smart已经发布有段时间了,其实我之前也写过几篇关于rt-smart的文章,但是都是关于CMake构建工程的文章。 而对我来说一直想在用户态操作一下底层硬件的东西。而在
    的头像 发表于 01-15 13:41 2610次阅读
    <b class='flag-5'>rt-smart</b>中的imx6ull用户态点灯

    树莓派上rt-smart的应用编程入门

    我们从现在开始会逐步连载RT-Thread Smart(简称rt-smart,甚至有时会称为smart os)的介绍文章,旨在让大家认识,接触到sm
    的头像 发表于 05-13 14:10 2842次阅读
    树莓派上<b class='flag-5'>rt-smart</b>的应用编程入门

    rt-smart移植分析:从树莓派3b入手

    移植rt-smart到最新的板子上具体需要注意哪些细节,哪些才是移植rt-smart的关键点?本文从树莓派3b上移植rt-smart的角度,从头分析
    发表于 01-25 18:48 0次下载
    <b class='flag-5'>rt-smart</b>移植<b class='flag-5'>分析</b>:从树莓派3b入手

    优雅的在D1S上运行RT-Smart

    前言 最近在学习 RT-Smart ,正巧有在全志开发者论坛看到这么一篇帖子【惊】在麻雀上运行国产rt-smart系统,看到很多人都在关注 D1S 在 Smart 上的运行情况。如今该
    的头像 发表于 11-16 20:15 2121次阅读

    丝滑的在RT-Smart用户态运行LVGL

    开发流程 1、RT-Smart 环境搭建 下载 RT-Smart 用户态应用代码: 1 git clone https: //github.com/RT-Thread/userapps
    的头像 发表于 11-22 20:20 1025次阅读

    RT-Smart riscv64汇编注释

    rt-smart在全志D1上的代码为例,主要注释了rt-smart在riscv64上的系统初始化和异常处理的代码仓库地址https://gitee.com/rtthread/rt
    的头像 发表于 02-08 21:40 877次阅读

    RT-Smart riscv64汇编注释

    rt-smart在全志D1上的代码为例,主要注释了rt-smart在riscv64上的系统初始化和异常处理的代码
    的头像 发表于 10-12 17:26 410次阅读
    <b class='flag-5'>RT-Smart</b> riscv64汇编注释

    RT-Smart应用开发笔记:fopen造成文件被清空问题的分析记录

    RT-Smart 应用(apps)开发环境,ubuntu 20.04 + win10 VS Code
    的头像 发表于 10-20 16:01 364次阅读
    <b class='flag-5'>RT-Smart</b>应用<b class='flag-5'>开发笔记</b>:fopen<b class='flag-5'>造成</b>文件被清空问题的<b class='flag-5'>分析</b><b class='flag-5'>记录</b>