freeRTOS的栈溢出检测机制

news2024/11/18 17:42:25

1、前言

  • 后面的分析是以RISC-V架构为例,不同的架构在代码实现上有些许区别
  • RISC-V架构使用的满减栈

2、任务控制块介绍(TCB:task controller Block)

typedef struct tskTaskControlBlock   
{
    volatile StackType_t * pxTopOfStack; 	//当前任务使用的栈空间地址,也就是SP指向的地址
    ListItem_t xStateListItem;         
    ListItem_t xEventListItem;               
    UBaseType_t uxPriority;                   
    StackType_t * pxStack;  //记录分配给任务的栈空间的最低地址                    
    char pcTaskName[ configMAX_TASK_NAME_LEN ];
}
  • 对FreeRTOS的任务机制不熟悉的可参考博客:《freertos任务调度机制深度分析(以RISC-V架构为例)》;

3、第一种:切换任务时检查当前栈指针是否溢出

3.1、检查栈溢出的逻辑

在这里插入图片描述

  • TCB->pxStack指向任务栈空间的最低地址
  • TCB->pxTopOfStack可以理解成当前使用到的栈地址
  • 栈从高地址向低地址使用,最后一个可用的栈空间地址就是TCB->pxStack,其中软件可以限制保留栈空间最后一小段空间,即[TCB->pxStack, TCB->pxStack+portSTACK_LIMIT_PADDING]这段区间的栈空间不可用
  • 在切换任务时,检查当前使用的栈地址是否小于TCB->pxStack+portSTACK_LIMIT_PADDING,如果小于,则说明栈空间已经溢出。
  • TCB->pxTopOfStack落在[TCB->pxStack, TCB->pxStack+portSTACK_LIMIT_PADDING]区间还不是真正意义上的栈溢出,只是软件上保留了部分栈空间,还可以挽救,可以理解成警告当前栈空间不足
  • 如果TCB->pxTopOfStack < TCB->pxStack,则真正发生了栈溢出,已经发生内存踩踏

3.2、FreeRTOS中的源码

//vApplicationStackOverflowHook:用于处理栈溢出的函数
#define taskCHECK_FOR_STACK_OVERFLOW()                                                            \
{                                                                                                 \
    /* Is the currently saved stack pointer within the stack limit? */                            \
    if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING )           \
    {                                                                                             \
        vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
    }                                                                                             \
}

3.3、性能分析

  • 每次在任务切换时都会检查,需要消耗部分性能,但是判断逻辑简单
  • 切换任务时的检查,只能判断当前是否发生栈溢出。
  • 无法检测任务执行时是否发生栈溢出。如果在任务执行时发生栈溢出,但是在切换任务时,栈空间已经被释放,在切换时的栈指针又指向栈空间,这是检测不出来的。

4、第二种:切换任务时检查栈空间最后16个字节是否曾被使用

4.1、检查栈溢出的逻辑

在这里插入图片描述

  • 在创建任务时,把任务的栈空间赋值成特殊值
  • 在切换任务时,检查栈空间的最后一小段是否被改写过
  • 如果不是特殊值则说明该段栈空间被使用过,则认为任务栈空间不足,曾经发生过栈溢出

4.2、FreeRTOS中的源码

 #define taskCHECK_FOR_STACK_OVERFLOW()                                                            \
 {                                                                                                 \
     const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack;                       \
     const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5;                                        \
                                                                                                   \
     if( ( pulStack[ 0 ] != ulCheckValue ) ||                                                      \
         ( pulStack[ 1 ] != ulCheckValue ) ||                                                      \
         ( pulStack[ 2 ] != ulCheckValue ) ||                                                      \
         ( pulStack[ 3 ] != ulCheckValue ) )                                                       \
     {                                                                                             \
         vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
     }                                                                                             \
 }

4.3、性能分析

  • 每次切换时都要判断一小段栈空间的值,会带来不小的性能开销
  • 能够检查出发生过栈空间溢出,但是不能定位到是何时何地发生过栈空间溢出
  • 栈空间的特殊值被修改,不一定是任务本身发生栈空间,也可能是其他任务发生了内存越界,修改了本任务的栈空间内容

5、总结

  • 上面介绍的两种栈空间溢出检测机制,基本只能检测出是否发生过栈空间溢出,不好定位是何时何地发生栈空间溢出
  • 更多是用来判断当前分配给任务的栈空间是否足够,如果发生异常则给任务多分配点栈空间
  • 两种任务检查机制都会消耗性能,可以在DEBUG版本程序进行栈空间溢出检测,在RELEASE版本程序关闭栈空间溢出检测机制,以节省性能开销
  • 还有硬件的异常检测机制,参考博客:《四种“栈溢出检测方法”实现分析(2种纯软件、一种纯硬件、一种软硬件结合)》;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1358981.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis基础学习一

1. Redis 入门 1.1. Redis 诞生历程 1.1.1.从一个故事开始 08 年的时候有一个意大利西西里岛的小伙子&#xff0c;笔名 antirez&#xff08;http://invece.org/&#xff09;&#xff0c;创建了一个访客信息网站 LLOOGG.COM。有的时候我们需要知道网站的访问情况&#xff0c;…

计算化学顶刊封面!玻色量子联合上海交大张健课题组发表量子计算重要成果

​2023年12月13日&#xff0c;北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;联合上海交通大学在中科院分区1区、计算化学领域Top刊物JCTC&#xff08;Journal of Chemical Theory and Computation&#xff09;内刊的封面上发表了以“Encoding Molecul…

两步带你解决IDEA 插件下载安装慢、超时、不成功问题

两步带你解决IDEA 插件下载安装慢、超时、不成功问题 1. 查找 国内插件的节点IP地址2. 修改本地hosts文件 > 今天在安装idea中的插件时&#xff0c;又双叒叕出现了这个问题&#xff0c;下载一个几MB的插件巨慢&#xff0c;所以写一下它的解决方案 1. 查找 国内插件的节点IP地…

中国文化文物和旅游统计年鉴,数据含pdf、excel等格式,文本形式呈现,可预览数据

基本信息. 数据名称: 中国旅游统计年鉴 数据格式: pdf、xls不定 数据时间: 2012-2020年 数据几何类型: 文本 数据坐标系: —— 数据来源&#xff1a;文化和旅游部、网络公开数据 原名为《中国旅游统计年鉴》2020年后更名为《中国文化文物和旅游统计年鉴》&#xff…

MongoDB批量写入操作

一、概述 MongoDB为客户端提供了批量执行写入操作的能力。批量写入操作影响单个集合。MongoDB允许应用程序确定批量写入操作所需的可接受确认级别。 db.collection.bulkWrite&#xff08;&#xff09;方法提供了执行批量插入、更新和删除操作的能力。 MongoDB还支持通过db.col…

跨境电商干货!独立站流量七大来源,这些你都知道吗?

如果要问做跨境电商独立站最烧钱的地方在哪里&#xff0c;那肯定就是流量推广这一块了&#xff0c;这也是做跨境电商独立站的必修课&#xff0c;要给我们的独立站引流&#xff0c;首先必须知道独立站流量从哪里来&#xff0c;今天龙哥就给大家盘点独立站七大流量来源&#xff0…

This error originates from a subprocess, and is likely not a problem with pip

我遇这个问题是的原因是包名错误 注意检查包名

SSM图书管理系统完整版

1.系统开发环境 开发工具&#xff1a;eclipse &#xff0c;SQLyog Community 数据库&#xff1a;mysql 8.0开发环境&#xff1a;jdk1.8 , tomcat 8.5后端框架&#xff1a;ssm 前端技术&#xff1a;htmlcssjavascript , layui&#xff0c;jquery&#xff0c;ajax 2.系统功能介绍…

WSL 与真实 linux 环境区别有多大?

随着 Windows 系统的不断发展和完善&#xff0c;WSL&#xff08;Windows Subsystem for Linux&#xff09;作为 Windows 10 的一个功能&#xff0c;为 Windows 用户提供了一个可以在 Windows 环境下运行 Linux 二进制可执行文件的环境。然而&#xff0c;尽管 WSL 为用户提供了一…

Charles的基础使用教程【Mac】

目录 1.安装 2.抓取https请求的前置操作 2.1安装证书&#xff1a; 2.2、SSL代理设置 3.Charles初识 1.安装 官网Charles下载安装即可&#xff0c;没有什么需要注意的地方 2.抓取https请求的前置操作 2.1安装证书&#xff1a; 未安装证书是这样的&#xff1a; 上述我们可…

南某人:从工厂到品牌的华丽转身!

南某人&#xff0c;这个名字在中国的市场上已经响当当&#xff0c;但你知道吗&#xff1f;这个品牌其实并没有自己的工厂和门店。那么&#xff0c;他们是如何做到年收入高达40亿的呢&#xff1f; 起初&#xff0c;南某人和许多中国品牌一样&#xff0c;从生产保暖内衣起家。然…

Golang里空结构体struct{}的介绍和使用

s t r u c t struct struct是 G o l a n g Golang Golang里的关键字&#xff0c;用于定义结构类型 比如 type Student struct{id intname string }struct{}是有 0 0 0个元素的结构体. struct{}{}表示类型struct{}的值为空{} 1.性质 1.1不占用内存 大小为 0 0 0&#xff0c;…

结合 Java Swing 实现 Java 文件和 JAR 包的拖拽执行

相关文章&#xff1a; 自己动手写分布式任务调度框架 之前开发了一个简易的分布式任务调度框架&#xff0c;任务的调度源头是通过各个业务服务的主动注册来实现的。当时有朋友提出可以添加一种任务来源&#xff0c;让用户能够手动将代码上传到调度平台并执行。所以在当时就“…

从《数据库索引设计与优化》看mysql索引设计

很久之前写的一篇文章&#xff0c;主要是结合mysql45讲和《数据库索引设计与优化》讨论索引设计的&#xff0c;拿出来分享下。 选用什么引擎 对于INSERT_SELECT型数据库&#xff0c;如果没有事务的要求&#xff0c;更倾向于选择MyISAM。 因为InnoDB会维护更多的数据&#xff…

Git如何将多个commit合并一个commit

问题场景&#xff1a;我在fork的仓库提交多个commit后&#xff0c;准备向原仓库提交pr&#xff0c;但是原仓库要求一个pr一个commit&#xff0c;因此需要先将这些commit合并为一个。 1.先拿到要合并的commit中最早的一个的commit id&#xff0c;然后进入仓库&#xff0c;使用如…

2024年山西省安全员C证证模拟考试题库及山西省安全员C证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年山西省安全员C证证模拟考试题库及山西省安全员C证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;山西省安全员C证证模拟考试题库是根据山西省安全员C证最新版教材&#xff0c;山西省安全员C证大纲整理…

NX二次开发中如何从对象选择控件中获得选中面的TAG值

一、概述 在NX二次开发中所有的对象操作都是通过对对象的TAG值进行操作控制&#xff0c;如何结合BlockUI控件&#xff0c;得到对象的TAG值是十分重要的一步。今天就遇到了这个问题&#xff0c;其实不是不会&#xff0c;而是思维习惯&#xff0c;直接利用对象选择器->Tag()&a…

杨中科 ASP.NETCore Rest

什么是Rest RPC 1、Web API两种风格: 面向过程(RPC) 、面向REST (REST) 2、RPC:“控制器/操作方法“的形式把服务器端的代码当成方法去调用。把HTTP当成传输数据的通道&#xff0c;不关心HTTP谓词。通过QueryString请求报文体给服务器传递数据。状态码。比如/Persons/GetAll…

[Vulnhub靶机] DriftingBlues: 3

[Vulnhub靶机] DriftingBlues: 3靶机渗透思路及方法&#xff08;个人分享&#xff09; 靶机下载地址&#xff1a; https://download.vulnhub.com/driftingblues/driftingblues3.ova 靶机地址&#xff1a;192.168.67.19 攻击机地址&#xff1a;192.168.67.3 一、信息收集 1.…

离线Vscode 安装完成后 添加到右键菜单

复制下面代码&#xff0c;修改文件后缀名为&#xff1a;reg Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\*\shell\VSCode] "Open with Code" "Icon""D:\\_Porgram_IT\\VsCode\\Code.exe"[HKEY_CLASSES_ROOT\*\shell\VSCode\comman…