158、【OS】【Nuttx】【栈溢出】中断栈不检查(一)

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

背景

上篇 blog
【OS】【Nuttx】【栈溢出】-finstrument-functions(二)

分析了 -finstrument-functions 官方描述中的括号补充说明:为什么需要 call_site 参数,并分析了内联函数中的插桩机制,并推荐以 static inline 为主,最后介绍了可以通过 __attribute__((no_instrument_function)) 属性来避免插桩,并分析了几种常见的不可插桩的场景,下面继续分析

栈溢出检测

OK,回到 Nuttx 的技术文档

这里提到了 Nuttx 栈溢出检测中的一个关键技术限制(中断栈无法检查),这里 stack penetration 表示栈溢出,和 stack overflow 一个意思,都表示 SP 超过了分配的栈空间

先说结论:正常任务运行时,rBS 存的是该任务的栈底地址,当发生中断时,CPU 直接跳转到 ISR,而不会更新 rBS(这里有点复杂,等会儿分析原因) ,所以在 ISR 中,rBS 仍然是被中断任务的栈底,而不是 ISR 自己的栈底,因此如果在 ISR 中执行栈检查(通过 -finstrument-functions 插桩),那插桩函数会拿 ISR 的栈指针 SP 去和任务的栈底 rBS 去比较,从逻辑上说就有点问题

所以基于函数调用的栈检查,无法同时用于中断服务程序 ISR,因为缺少 ISR 专属的栈基址信息 ,所以这也是 arm_stackcheck.c 中注释里提到的:主动跳过中断中的栈检查,避免误报或崩溃

OK,下面来详细分析下中断栈不进行溢出检测的原因

中断服务程序 ISR 在运行时,CPU 不会自动切换任务上下文 (Nuttx 中的 task_context,这个是调度任务才需要的背景内容),只是在当前任务的执行流中,临时打断一下,去处理中断,因此保留了被打断任务的所有寄存器状态(包括 rBS),所以也不会为 ISR 去单独设置新的栈基址

在硬件层面,以 ARM Cortex-M 为例,当异常(中断)发生时,Cortex-M 内核自动压栈 R0R1R2R3R12LRPCxPSR 等 8 个寄存器, 注意,不包括 R4 ~ R11,也不包括 rBSR10),这些寄存器被压到当前使用的栈空间(被中断任务的栈空间,或独立的中断栈空间),然后 CPU 切换到 Handler 模式(特权级别),栈指针 SP 根据是否有独立的中断栈空间来决定是否发生变化

然后 rBS 是 Nuttx 的软件约定,只有 Nuttx 知道是用 R10 寄存器来保存当前任务的栈底地址,R10 并不是 ARM 架构的标准寄存器,而是 RTOS 为了高效栈检查而使用的通用寄存器,所以 CPU 并不知道 rBS 的存在,所以硬件中断机制完全不知道 Nuttx 用 R10 存了栈底地址,所以进入 ISR 时,CPU 也不会自动保存和恢复 R10,也不会更新这个寄存器,所以 R10 的值仍然是被中断任务的栈底

OK,接着来解释下,OS 为什么不在中断服务程序更新 rBS,虽然硬件不会去更新这个寄存器,但是软件可以做嘛,那为什么 Nuttx 不在 ISR 入口处更新 rBS 栈底呢?这个软件虽然理论上可以,但代价太高,而且没必要,有几个原因来分析下

首先是中断服务程序 ISR 可能使用不同的栈,在 Cortex-M 中,有两种栈

  • 主栈(MSP):用于 Handler 模式,包括 ISR
  • 进程栈(PSP):用于 Thread 模式(任务)

当任务运行时,使用 PSP 进程栈,当发生中断后,会自动切换到 MSP(需要配置),所以 ISR 实际运行在另一个栈空间(主栈),而 rBS 存的是任务栈底,如果在 ISR 中,用任务栈底 rBS 去检查 SP,就是拿 MSP(ISR 栈)和任务栈底 PSP 做比较,那就毫无意义


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

相关推荐
mifengxing10 天前
操作系统(三)
操作系统·多线程·os·进程信息传递
551只玄猫13 天前
【操作系统原理 实验报告6】磁盘调度算法
算法·操作系统·os·实验报告·操作系统原理·磁盘调度算法·磁盘调度
AMoon丶14 天前
Golang--内存管理
开发语言·后端·算法·缓存·golang·os
HIT_Weston21 天前
170、【OS】【Nuttx】【ARMV7M】任务跳转(上下文切换)(一)
os·nuttx·armv7m
HIT_Weston21 天前
171、【OS】【Nuttx】【ARMV7M】任务跳转(上下文切换)(二)
os·nuttx·armv7m
Charlie__ZS22 天前
Ubuntu 22.04新建用户,并赋予管理权限
linux·os·ubuntn
ErizJ23 天前
面试 | 操作系统
linux·面试·职场和发展·操作系统·os
HIT_Weston24 天前
169、【OS】【Nuttx】【栈溢出】up_initial_state(IPSR&EPSR)
os·栈溢出·nuttx
HIT_Weston1 个月前
162、【OS】【Nuttx】【栈溢出】中断栈行为(双栈模型)
os·栈溢出·nuttx