155、【OS】【Nuttx】【栈溢出】安全边距(二)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【OS】【Nuttx】【栈溢出】安全边距(一)

分析了栈溢出检测的过程,以及安全边距在没有独立 ISR 中断栈,和有独立的 ISR 中断栈两种场景下的计算过程,下面继续分析

栈溢出检测

最后一句可以看到,不管有没有独立的 ISR 中断栈,任务栈都应该至少多分配 200 字节作为安全边际

这也是工程实践中的宝贵经验,别把栈分配得刚刚好,一定要留点余量 ,这也符合中华的中庸之道,不把事情做绝,举个例子,如果通过性能分析(比如通过 Stack Monitor 进行染色),发现某个任务最多使用了 800 字节的栈空间

那这时候

  • 错误做法 :给这个任务分配刚刚好 800 字节栈空间(中断一上来就会崩溃)
  • 正确做法:分配 800 + 200 = 1000 字节(或向上对齐到 1024,多留些安全余量)

这样即使发生中断,任务栈也有足够空间保存上下文,不会破坏掉其他内存

不过接下来又引出一个问题,即使预留了 200 字节的安全余量,是否就能保证中断进来就是安全的呢?答案是不一定,这个问题也是嵌入式系统中,中断栈安全最核心,也最容易被忽视的风险点之一 :即使预留了 200 字节给上下文保存,但如果 ISR 中断服务程序内部声明了大数组,或者出现深度嵌套中断调用,也依然会出现栈溢出!,这也是真实世界中,导致系统崩溃的常见原因

Nuttx 这里的 200 字节,只考虑了硬件自动压栈的部分,也就是 CPU 在进入中断时,自动保存的寄存器(由 ARM 架构决定),这部分是确定性的,最小开销 ,但这 200 字节并没有考虑 ISR 函数本身的栈使用(所以不要误会,200 字节只是预留的最小安全距离,并不能保证中断栈就安全),这是因为

  • 即便是 Per function Call 栈检查机制,其本身也无法监控 ISR,如下描述,R10(rBS)在 ISR 中不会更新,所以 __cyg_profile_func_enter 在 ISR 里检查的是任务的栈底,而不是 ISR 的实际可用空间 ,即使 ISR 溢出,也不会触发 Hard Fault(除非刚好踩到 MPU 保护区域)
  • 另外,ISR 的栈使用是软件行为,不可预测,编译器也不可能知道 ISR 会用多少栈空间,而开发者也可能不小心写个 char buf[512]; 在 ISR 里面

OK,在工程实践中,有一些方法可以尽量避免 ISR 栈溢出,下面来看下

  • 使用独立的 ISR 栈 ,这也是之前提到两种场景之一,给中断提供独立的栈空间,可以减少对任务栈的消耗 ,比如 Nuttx 可以通过配置 CONFIG_ARCH_INTERRUPTSTACK让系统为所有中断分配一个专用,足够大的栈空间(比如 1~2 KB),实现任务栈和 ISR 栈的完全分离 ,这样的话
    1、任务栈只需要预留少量切换开销
    2、ISR 的栈空间使用不会影响任何任务
    3、可以单独为 ISR 栈空间做监控(虽然 Nuttx 默认不检查 ISR 栈空间)
  • 严格限制 ISR 的行为,比如规定在 ISR 中禁止
    1、声明大数组
    2、调用复杂函数(尤其是递归或深度嵌套)
    3、使用 malloc 动态内存分配
    ISR 应该只做一些简单的事情 ,比如
    1、清中断标志位
    2、发信号量,队列通知等
    3、快速记录状态
    4、做完简单的事情后,尽快退出,把耗时的工作交给任务处理

在 MISRA C,AUTOSAR 等安全标准都明确规定,ISR 必须短小,确定,无栈膨胀


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【OS】【Nuttx】【栈溢出】-finstrument-functions(一)

相关推荐
HIT_Weston2 天前
154、【Nuttx】【OS】【启动】栈溢出检测(一)
os·nuttx·栈监控
HIT_Weston5 天前
153、【Nuttx】【OS】【启动】回归!继续 Nuttx 探索(Stack Monitor)
os·nuttx·栈监控
啊阿狸不会拉杆25 天前
《计算机操作系统》第十章 - 多处理机操作系统
c++·算法·计算机组成原理·os·计算机操作系统
啊阿狸不会拉杆25 天前
《计算机操作系统》 第十一章 -多媒体操作系统
开发语言·c++·人工智能·os·计算机操作系统
啊阿狸不会拉杆25 天前
《计算机操作系统》 - 第九章 操作系统接口
人工智能·算法·计算机组成原理·os·计算机操作系统
啊阿狸不会拉杆1 个月前
《计算机操作系统》第七章 - 文件管理
开发语言·c++·算法·计算机组成原理·os·计算机操作系统
啊阿狸不会拉杆1 个月前
《计算机操作系统》第六章-输入输出系统
java·开发语言·c++·人工智能·嵌入式硬件·os·计算机操作系统
啊阿狸不会拉杆1 个月前
《计算机操作系统》第四章-存储器管理
人工智能·算法·计算机组成原理·os·计算机操作系统
LiRuiJie1 个月前
从OS层面深入剖析JVM如何实现多线程与同步互斥
java·jvm·os·底层