Stack overflow detection
FreeRTOS官方给了两种内存溢出检测方案:
FreeRTOS - stacks and stack overflow checkingFreeRTOS is a portable, open source, mini Real Time kernel. A free RTOS for small embedded systemshttps://www.freertos.org/Stacks-and-stack-overflow-checking.html【进阶】三种" 堆栈溢出检测 "方法,请拿去吹牛!_最后一个bug的博客-CSDN博客1、聊一聊 分享一首非常洒脱自在的歌曲! 本文主要是跟大家分享三种堆栈溢出检测的方法,也算是接着之前分享的堆栈溢出分析的续篇。2、正文部分在阅读本文前建议大伙阅读往期文章 ...
https://blog.csdn.net/qq_33471732/article/details/112343334
“Stack overflow checking introduces a context switch overhead so its use is only recommended during the development or testing phases.”
FreeRTOS的堆栈检测需要一个上下文切换操作,因此会增加系统时间开销,推荐在开发和测试阶段使能该功能。
第一种方式:
将一个线程交换出去(从运行态切换成就绪态或者阻塞态),这时候内核会将线程的上下文内容压入线程栈中去,内核会检测栈顶指针是否在有效栈空间内,如果不在的话说明发生了栈溢出。
第二种方式:
在创建线程的时候,将线程的栈内容都赋值一个特殊的值(Magic Number,例如0x11223344),检测的时候,触发一次内核调度,将线程交换出去,然后内核检测线程栈的最后16个字节的内容,如果最后16个字节的值和预设的值不一致,表示可能发生了栈溢出(不排除野指针、程序跑飞导致的内容篡改)。
上面的这几种方式有两个十分明显的缺点,第一个是占用额外CPU时间,第二个是无法100%检测到栈溢出,因为上诉的方法是通过定时检测的方式检测是否溢出,所有有时候由于较严重的堆栈溢出时会直接导致程序卡死或者数据异常中断而来不及检测,甚至大数组局部变量直接跳过预设值区域,导致堆栈检测失效等问题。
除了以上FreeRTOS提供的几种方式之外,还有一种方式针对带有MPU单元的处理器。MPU就是内存保护单元,它的一个功能是控制某一段或者多段内存空间的访问权限,例如可读可写或不可访问,试图放翁不可访问的内存空间时产生异常,利用这个特性可以做到栈溢出检测。在创建线程的时候,栈空间可以多分配一些,例如多分配64个字节(最小值取决于MPU支持的最小管理单元大小),这样在内核交换进某一个线程的时候,使用MPU设置它的栈尾64个字节的空间为不可访问,如果这个线程出现栈溢出,那大概率是入栈时访问到了最后64字节空间,这时候就会出现异常。