Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
死机
链表
RT-Thread 使用经验分享 :链表未初始化造成死机
发布于 2023-03-18 10:30:44 浏览:592
订阅该版
[tocm] ## 前言 - 最近在开发调试基于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,必须初始化,否则把链表节点插入 链表头部的时候,就会出现 野指针或空指针 访问成员的问题,肯定会出问题。 ![2023-03-18_102302.png](https://oss-club.rt-thread.org/uploads/20230318/71707f76a820be2e70cd491b086ed706.png) - 解决方法就是 增加链表初始化操作 ![2023-03-18_102440.png](https://oss-club.rt-thread.org/uploads/20230318/b700b51459125f1a8f7385d2239da452.png) ## 问题回顾 - 由于先前移植的样板驱动使用的是 `hash list`,造成移植后没有初始化数据结构的链表节点,触发了死机。所以驱动移植时,遇到链表时,一定要注意 链表头与链表节点的 链表初始化问题 - 另一个注意点:操作空指针的成员,异常信息里面,可能会提示 异常出在一个 较小的 内存地址上。所以遇到死机,并且发现死机的 内存地址很小,可以往 空指针方向排查 - RT-Thread 双向循环链表的操作,由于使用的是【宏定义】,也就是链表操作函数本身没有判空的操作,用户需要有链表指针判空的操作。 - 访问一个空指针的结构体成员,肯定会触发内存异常死机。 如 `buffer->list` 中的 `list` 为 `RT_NULL`,那么访问 `buffer->list->next` 时候,`list` 中的 `next` 成员地址就是非法的内存地址(小地址),就会出现异常死机 ## 小结 - 链表操作需要谨慎,不只是要把 链表头 申请为 全局的,而且每个链表的节点,都是需要全局的。 - 注意链表节点会嵌入到一个复杂的数据结构里面,并且使用动态内存申请的方式 创建,这是一定要注意不要漏下 链表成员的初始化。
4
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
张世争
学以致用
文章
131
回答
805
被采纳
174
关注TA
发私信
相关文章
1
加了bootloader后,为什么就卡死了
2
free a bad data block导致机器死机问题咨询
3
stm32f429上运行动态模块,加载运行死机
4
开启Iwdt看门狗,为什么还会“死机”(硬件干扰)
5
cmBackTrace定位后无法分析出问题原因
6
rt_timer_start 链表死循环
7
hard fault on thread: lcd_task 问题?
8
telnet功能开启之后,断开网线则死机
9
官方的定时器案例死机
10
RT-thread nano不能进入线程,好像死机了
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部