稳定性问题总结
1 空指针问题:
本质为访问异常地址,但空指针问题较为显著,一些芯片也针对空指针存在对应的硬件异常(infineon tricore处理器)
- 函数入参错误,未检查是否为空指针就直接使用。
- 远端发送了错误的数据,未检查直接使用导致。(例如接收的二进制数据直接强转为结构体指针进行访问)
- 配置数据错误,未检查直接使用。
- 并发问题,使得数据被破坏,导致形成空指针访问。
处理方法:指针数据使用前一定要做检查,充分考虑可能存在多任务数据竞争,或任务与中断数据竞争。并使用合理的保护手段。
2 访问异常地址错误
尝试写不允许直接写的区域,例如一些片上的数据flash区域需要一些特定的前置条件,才能写。
函数/外部请求参数,数据异常,未做检查的条件下直接使用,导致访问异常地址。
版本兼容性问题导致。
- 例如,发送/接收端使用的数据类型定义格式不一定,导致一方解析错误,访问错误数据。
- 例如,一些特定数据会放在热复位不丢失的retention ram区域,系统升级后可能会继续使用这些数据。该区域数据如果在当前版本和升级版本间不兼容,则可能会引起访问异常。
- 例如,模块以lib库形式交付,模块提供方更新了lib库,但使用方未更新头文件。
- 编译环境差异
C 强制类型转换错误,对二进制数据进行强制类型转换时,使用了错误的指针类型,导致后续访问异常。
处理方法:合理的代码集成流程规范。程序编写者需要充分考虑是否存在兼容性场景以及对应的措施。具体代码逻辑中,合理地对外部输入进行数据检查。
3 内存踩踏相关:
- 中断栈溢出
- 任务栈溢出
- 应用数据溢出(如buffer变量写越界)
- 程序错误、逻辑错误等原因导致对非目标地址进行了写操作
处理方法: 使用MPU,对数据读写进行保护。如果不使用MPU,数据踩踏造成的问题往往在第二现场才体现(使用异常数据的地方触发硬件异常,而不是破坏数据的地方),第二现场往往存在随机性,正向排查导致数据被破坏的根因难度大。
4 并发问题:
数据并发保护场景未覆盖全,导致出现数据竞争,使得目标数据被破坏,引起后续访问出现异常。一般竞争场景有:
- 单核任务与任务间数据竞争
- 单核任务与中断间数据竞争
- 单核中断与中断间数据竞争
- 多核任务/中断间数据竞争
处理方法:所以非单线程访问数据,建立充分的数据访问模型/状态机,充分考虑所有可能的并发场景。
5 地址对齐问题:
一些处理器中对数据访问的地址对齐要求比较严,不允许非对齐访问。一般问题根因有:
- 接收外部二进制数据后,强转为特定类型指针数据进行访问时,可能引起非对齐访问问题。
- 一些场景下,相关变量定义未强制使用attribute属性进行地址对齐。(例如,定义char 数组,后续按int进行访问)
- 使用了紧凑模式定义结构体类型时,需要考虑成员的排布,避免导致非对齐问题。
处理方法:根据使用场景,合理排布结构体成员排布、地址对齐声明。
6 调度异常相关问题:
- 单核锁 mutex 使用不规范,形成死锁。
- 临界区(单核)使用不规范
- 在临界区中使用会导致系统阻塞的api,阻塞型api内部可能因当前api条件不满足而让出cpu,又由于在临界区内导致无法成功让出cpu,可能不符合os代码逻辑的预期,导致系统异常。
- 在临界区中使用的 api,内部可能又打开了中断,引发非预期调度,破坏了预期的保护目的
- 核间锁(spinlock)使用不规范,spinlock一般由硬件提供相应机制实现。使用spinlock应该保护逻辑简单、纯粹的代码。如果在保护代码段中使用了 OS 中会引起调度的api,则可能会引入并发问题,破坏保护的初衷。
- 在受控中断中,使用了错误的api接口(非中断专用接口),在不受控中断中,使用了os 的api(通常os设计上,不允许这种使用场景,会破坏内核中的临界区保护目的)
- 跨核保护场景,错误使用了单核 mutex 进行保护(导致core A上的任务被异常调度到 core B上)。
处理方法:识别保护场景,并且做到任何保护方式,所保护的代码尽量做到为纯逻辑代码、不涉及 os 或其它模块api的调用。
7 资源使用问题:
- 全局资源使用不均衡,未进行合理管控。单一模块异常时(异常使用了全部的全局资源),导致其它模块功能失效。如 lwip的网络资源。
处理方法:给不同模块分配各自份额,并进行合理限流。
8 CPU 负载相关问题:
- CPU利用率不均衡,出现周期性波峰波谷。
- 不同核CPU利用不均衡,出现一些核心cpu利用率极低。
- CPU 利用率被打满
- 任务优先级设置不合理
处理方法:合理排布不同核上的任务分布和任务优先级,使各核心利用率达到均衡。针对性分析造成周期性波峰的任务特征,对其执行逻辑进行合理的均匀化。 排查造成cpu利用率被打满的任务,一般是由于该任务出现异常导致,或任务逻辑实现低效导致。