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

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

3天内不再提示

RT-Thread使用经验分享:链表未初始化造成死机

冬至子 来源:张世争 作者:张世争 2023-10-08 14:49 次阅读

前言
最近在开发调试基于RT-Thread 的驱动时,遇到一个比较奇怪的死机问题,后来经过一步步排查,终于发现是驱动的链表节点没有初始化造成的死机

问题分析
RT-Thread 的驱动开发完成后,通过编写串口 shell 测试命令,运行命令后,触发死机

由于当前缺少单步的调试方法,只能通过增加LOG与打开关闭部分软件功能,一步步缩小范围

在函数调用的入口,把某些关键的函数调用分别注释掉验证,这样逐步验证下来,最终缩小到一个函数,调用这个函数就触发死机。

用到的软件调试方法
(1)增加LOG,确认代码能执行到哪些函数,能执行到哪些行

(2)通过 #if 0 A_CODE #else B_CODE #endif 条件编译的调试方法,大块注释部分代码,确认代码执行的路径,缩小排查方向,确认是执行到哪个函数或模块造成死机的

(3)通过对比代码来确认问题,比如软件正常工作过,后来改动死机了,大概率说明是改动造成的,所以可以通过 git BCompare.exe 等代码管理与比对工具,代码回溯,两份新旧代码对比分析,逐步把排查范围缩小,从代码层面分析可能造成死机的原因

问题分析
软件调试有时候比较的简单,有时候会比较的复杂,由于这个驱动移植来自其他系统的,数据结构里面的成员比较的多,所以初步通过代码对比工具如 BCompare 进行代码对比,发现了一点端倪:由于RT-Thread 暂时不支持 hash list(哈希链表),我把 hash list的功能实现 改为了 RT-Thread 的 list 替代,struct rt_list_node。

对比了软件的其他改动点,虽然改动部分较大,但软件工作流程差不多,初步排查代码没有实质性的差异

通过进一步的排查并缩小范围,终于发现了问题点:这个函数在 插入链表 的操作部分死机了!

通过代码继续网上找,发现这个包含 RT-Thread list 的数据节点,是通过 rt_malloc 申请的,并且没有看到成员 list 使用 rt_list_init 初始化链表的操作

所以马上确认了问题: 链表的节点没有初始化造成的,通过增加 list 初始化,本以为立即解决了问题,但是竟然依旧死机!

意外的BUG发现:数据节点的链表的头,也就是 链表 head 也没有初始化,解决方法同上,需要初始化 链表的头:使用 rt_list_init,这样问题得到解决

移植的代码之前使用的 hashlist,声明时即初始化了,不需要显示的初始化,而RT-Thread list,必须初始化,否则把链表节点插入 链表头部的时候,就会出现 野指针或空指针 访问成员的问题,肯定会出问题。

1.jpg

解决方法就是 增加链表初始化操作

1.jpg

问题回顾
由于先前移植的样板驱动使用的是 hash list,造成移植后没有初始化数据结构的链表节点,触发了死机。所以驱动移植时,遇到链表时,一定要注意 链表头与链表节点的 链表初始化问题

另一个注意点:操作空指针的成员,异常信息里面,可能会提示 异常出在一个 较小的 内存地址上。所以遇到死机,并且发现死机的 内存地址很小,可以往 空指针方向排查

RT-Thread 双向循环链表的操作,由于使用的是【宏定义】,也就是链表操作函数本身没有判空的操作,用户需要有链表指针判空的操作。

访问一个空指针的结构体成员,肯定会触发内存异常死机。 如 buffer->list 中的 list 为 RT_NULL,那么访问 buffer->list->next 时候,list 中的 next 成员地址就是非法的内存地址(小地址),就会出现异常死机

小结
链表操作需要谨慎,不只是要把 链表头 申请为 全局的,而且每个链表的节点,都是需要全局的。

注意链表节点会嵌入到一个复杂的数据结构里面,并且使用动态内存申请的方式 创建,这是一定要注意不要漏下 链表成员的初始化。

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

    关注

    52

    文章

    8164

    浏览量

    146029
  • Shell
    +关注

    关注

    1

    文章

    363

    浏览量

    23297
  • RT-Thread
    +关注

    关注

    31

    文章

    1273

    浏览量

    39924
收藏 人收藏

    评论

    相关推荐

    RT-Thread自动初始化详解

    我们知道,在写裸机程序时,当我们完成硬件初始化后,就需要在主函数中进行调用。当我们使用RT-Thread后,完全不需要这样做了,我们可以将硬件等自动初始化RT-Thread 自动
    的头像 发表于 06-25 21:38 1.1w次阅读
    <b class='flag-5'>RT-Thread</b>自动<b class='flag-5'>初始化</b>详解

    RT-Thread内核对象初始化链表组织方式

    最近在看RT-Thread内核的源码,内核对象使用链表组织。
    发表于 06-02 09:48 718次阅读
    <b class='flag-5'>RT-Thread</b>内核对象<b class='flag-5'>初始化</b><b class='flag-5'>链表</b>组织方式

    RT-Thread qemu mps2-an385 bsp移植制作 :系统运行篇

    前面已经让 RT-Thread 进入了 entry 入口函数,并且 调整 链接脚本,自动初始化与 MSH shell 的符号已经预留, 进入了 RT-Thread初始化
    的头像 发表于 11-14 12:27 785次阅读
    <b class='flag-5'>RT-Thread</b> qemu mps2-an385 bsp移植制作 :系统运行篇

    RT-Thread 踩坑记录 - 初始化线程时使用局部变量

    前言为了不再CTRL+C,CTRL+V,修改,我开始尝试手敲代码。RT-Thread线程可以静态初始化,也可以动态申请内存的方式创建静态初始化线程静态初始化线程时,线程结构体与线程的栈
    发表于 05-13 18:40

    RT-thread初始化过程是怎样进行的

    RT-thread初始化过程是怎样进行的?扩展补丁Sub和super的作用是什么?如何去使用它们呢?
    发表于 11-29 07:42

    如何对RT-Thread系统进行初始化

    RT-Thread是如何启动的?如何对RT-Thread系统进行初始化呢?
    发表于 11-30 07:54

    RT-Thread内核学习资料汇总

    操作方法在内核文件 object.c 中实现4、RT-Thread内核对象初始化链表介绍  链表是一种数据结构,跟其他的结构体类似,初始化
    发表于 03-15 10:45

    RT-Thread自动初始化机制简介

    RT-Thread 的时钟管理以时钟节拍为基础,时钟节拍是 RT-Thread 操作系统中最小的RT-Thread 自动初始化机制时钟单位。RT-T
    发表于 04-06 18:08

    浅析RT-Thread中对象容器与双链表的操作

    _Object_Info_Unknown] ={ /* 初始化对象容器 - 线程 */ {RT_Object_Class_Thread,_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread
    发表于 05-18 14:23

    一文详解RT-Thread自动初始化

    在学RT-Thread时,经常能听到这个词:自动初始化。用起来也非常容易,一个宏就解决了,但是原理是什么呢?
    的头像 发表于 07-21 10:17 7542次阅读
    一文详解<b class='flag-5'>RT-Thread</b>自动<b class='flag-5'>初始化</b>

    RT-Thread 内核学习笔记 - 内核对象初始化链表组织方式

    RT-Thread 内核学习笔记 - 内核对象rt_objectRT-Thread 内核学习笔记 - 内核对象管理RT-Thread 内核学习笔记 - 内核对象操作APIRT-Threa...
    发表于 01-25 18:24 3次下载
    <b class='flag-5'>RT-Thread</b> 内核学习笔记 - 内核对象<b class='flag-5'>初始化</b><b class='flag-5'>链表</b>组织方式

    RT-Thread全球技术大会:如何使用组件以及自动初始化流程

    RT-Thread全球技术大会:如何使用组件和自动初始化流程           审核编辑:彭静
    的头像 发表于 05-27 15:16 904次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:如何使用组件以及自动<b class='flag-5'>初始化</b>流程

    RT-Thread自动初始化机制

      在分析之前首先查阅 RT-Thread 的官方文档 [RT-Thread 自动初始化机制](https://www.rt-thread.org/document/site
    的头像 发表于 06-17 08:52 2549次阅读
    <b class='flag-5'>RT-Thread</b>自动<b class='flag-5'>初始化</b>机制

    rt-thread线程栈初始化参数分析

    RT-Thread 在线程初始化的代码内有一段初始化线程堆栈的代码
    的头像 发表于 08-14 16:50 1623次阅读
    <b class='flag-5'>rt-thread</b>线程栈<b class='flag-5'>初始化</b>参数分析

    RT-Thread使用经验分享:动态申请的内存清零造成死机

    最近在开发调试基于RT-Thread 的程序时,遇到一个比较奇怪的死机问题,后来经过一步步排查,终于发现是动态内存申请的数据结构没有清零引发的死机
    的头像 发表于 10-08 14:59 968次阅读
    <b class='flag-5'>RT-Thread</b>使用<b class='flag-5'>经验</b>分享:动态申请的内存<b class='flag-5'>未</b>清零<b class='flag-5'>造成</b><b class='flag-5'>死机</b>