在FreeRTOS的资料上看到一种栈溢出检测方式,将任务栈的内容全部设为0xa5, 假设初始栈顶地址是&stack[1000], 那么我们可以检测栈底的一部分内容(假设是stack[16]-stack[0])是否被修改来判断栈是否溢出。资料提到一个弊端:有可能,栈末尾的16个字节没有用到,但是任务栈已经溢出了,这种检测不到。问题:压栈的时候都会按顺序压,压入一个字节sp减去1,怎么会有栈溢出了但是栈末尾的16个字节没有被修改的情况(排除压栈内容恰好是0xa5的情况)? 以下是原文: 任务创建的时候将任务栈所有数据初始化为 0xa5 ,任务切换时进行任务栈检测的时候会检测末尾的16 个字节是否都是0xa5 ,通过这种方式来检测任务栈是否溢出了。相比方法一,这种方法的速度稍慢些,但是这样就有效地避免了方法一里面的部分情况。不过依然不能保证所有的栈溢出都能检测到,比如任务栈末尾的16 个字节没有用到,即没有被修改,但是任务栈已经溢出了,这种情况是检测不到的。另外任务栈溢出后,任务栈末尾的16 个字节没有修改,但是溢出部分的栈区的数据修改了,这部分栈区的数据不重要或者暂时没有用到还不会有什么问题,但如果是重要数据被修改将直接导致系统进入硬件异常,这种情况下,栈溢出检测功能也是检测不到的。 |
调度器在压栈前就会检查栈空间, 不够的话, 它不会选择有多少就压多少的, 而是直接报错, 所以最后这一两个WORD没被改动。
但其实看到栈的顶部只剩几个WORD, 你就别多想了, 一定是栈空间不够了, 这次不出事, 下次问题都会找上门来的。
评分
查看全部评分
http://blog.csdn.net/jiejiemcu/article/details/87174666
评分
查看全部评分
任务被交换出去的时候,该任务的整个上下文被保存到它自己的栈空间中。这时任务栈的使用应当达到了一个峰值。当 configCHECK_FOR_STACK_OVERFLOW 设为1 时,内核会在任务上下文保存后检查栈指针是否还指向有效栈空间。一旦检测到栈指针的指向已经超出任务栈的有效范围,栈溢出钩子函数就会被调用。
方法 1 具有较快的执行速度,但栈溢出有可能发生在两次上下文保存之间(也就是任务正在运行的时候,很有肯溢出),这种情况不会被检测到,因为这种检测方式仅在任务切换中检测。
我的问题点在于:对于方法二,在何种场景下会发生“依然不能保证所有的栈溢出都能检测到,比如任务栈末尾的16个字节没有用到,即没有被修改,但是任务栈已经溢出了,这种情况是检测不到的”。
你的文章说的是这种情况几乎不可能出现,能否说一个场景,会出现这种末尾字节没有被改,但实际上栈溢出了??