在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Embedded Studio堆棧溢出預防簡析

麥克泰技術 ? 來源:麥克泰技術 ? 2023-07-14 11:07 ? 次閱讀

為了識別運行的嵌入式系統中的堆棧溢出問題,SEGGER編譯器通過為每個函數生成檢測代碼的方式來檢查堆棧溢出。該功能可以使用命令行開關-mstack-overflow-check來使能。對于安全系統,必須在溢出的堆棧破壞內存之前檢測到堆棧溢出,因此需要在更改堆棧指針和需大量堆棧空間之前進行檢查。

一,Embedded Studio的堆棧溢出預防

在Embedded Studio中啟用堆棧溢出預防功能,僅需將工程選項Code->Code Generation->Enable Stack Overflow Prevention設置為“Yes”。

如果工程中沒有實現錯誤回調函數__SEGGER_STOP_X_OnError,它默認保持在一個無限循環中。Embedded Studio安裝目錄$(StudioDir)/samples下的SEGGER_STOP.c中包含一個錯誤處理的示例實現。

二,編譯器生成的代碼

如果在編譯器中使能堆棧溢出檢查,生成的代碼將被改變,如下所示:

1、不使用堆棧的函數不會被更改。

2、使用本地堆棧幀但不使用R3傳遞參數的函數中:堆棧幀的設置(通常使用sub sp, #size指令)被替換為將所需棧大小加載到寄存器R3中,然后調用函數__SEGGER_STOP_GROW_R3()。

3、使用本地堆棧幀并使用R3傳遞參數的函數中,操作與2相同,但是使用寄存器R4傳值,并調用函數__SEGGER_STOP_GROW_R4()。這意味著,R4必須在進入函數時必須入棧。

4、不使用本地堆棧但需在堆棧中保存寄存器的函數中,在寄存器壓棧后將調用不帶參數的函數__SEGGER_STOP_GROW_0()。

5、需要動態分配堆棧的函數(如使用alloc()函數或可變大小的數組),編譯后代碼也將調用__SEGGER_STOP_GROW_R3()。因為分配可能發生在函數執行中,需指示寄存器分配器,確保R3可以使用。

然后,被調用的函數可以使用存儲在全局變量中的堆棧上限值檢查堆棧是否溢出。檢查函數將在需要保存的寄存器被壓棧后調用。因此,必須計算堆棧上限,以便始終有棧空間用于:

在函數入口處,入棧所有的通用寄存器(R0 - R11, LR),有一些優化可能導致R0 - R3入棧。

所有被調用者需保存的浮點/矢量寄存器(D8 - D15)

中斷入口需保存的寄存器 (8個字)

3個(備用)字用于對齊和緊急溢出緩存

可以使用__attribute__((no_stack_overflow_check))禁止生成單個函數的堆棧檢查代碼。

三、堆棧檢查和錯誤處理

啟用“防止堆棧溢出”功能時,必須實現下列堆棧檢查函數。在Embedded Studio中,這些函數已添加到標準庫中。

__SEGGER_STOP_GROW_R3

__SEGGER_STOP_GROW_R4

__SEGGER_STOP_GROW_0

堆棧溢出時,堆棧檢查函數應該跳轉到用戶提供的錯誤處理回調函數__SEGGER_STOP_X_OnError()。

堆棧檢查函數

編譯器生成的代碼調用檢查函數檢查剩余的堆棧大小,在堆棧溢出的情況下函數不能返回。為了提高效率,這些函數沒有遵循標準調用約定。因此,函數不能修改除了R12和包含堆棧大小參數的寄存器之外的任何寄存器,函數在返回之前還必須調整堆棧指針。

錯誤處理回調

為了確保錯誤處理回調不使用溢出堆棧,它應該在純匯編中實現,并且在禁用堆棧溢出檢查功能狀態下進行編譯。

在默認實現中,__SEGGER_STOP_X_OnError定義為:

__attribute__((naked, no_stack_overflow_check)) void __SEGGER_STOP_X_OnError(void);

它在堆棧檢查函數尾部調用,不遵循常規調用約定。堆棧上限值、新的堆棧指針值和調用者通過R3、R12和LR傳遞。

錯誤處理回調可能會將溢出堆棧重置為安全值。同時,它可能會調用其他函數,比如記錄錯誤和重置系統。

示例:

void __SEGGER_STOP_X_OnError(void) {
  asm(
      "cpsid i
"                       // Disable interrupts
      "mov     r0, r12
"               // Save overflowed SP
      "mov     r1, r3
"                // Save SP limit
      "sub     r2, lr, #5
"            // Save caller
      "mrs     r3, CONTROL
"           // Get currently used stack
      "lsls    r3, #30
"
      "ittee   pl
"                    // Reset this stack
      "ldrpl   r12, =__stack_end__
"
      "msrpl   msp, r12
"
      "ldrmi   r12, =__stack_process_end__
"
      "msrmi   psp, r12
"
      "bl _HandleStackError
"            // Call error handler
      "b .
"                             // Stay here
      );
}

四、堆棧上限

啟動代碼必須初始化堆棧上限,至少初始化主堆棧上限變量__SEGGER_STOP_Limit_MSP。在默認實現中,該符號由運行時初始化代碼自動初始化為默認值。

為了調整上限值,例如改變為保存寄存器保留的空間,以及初始化__SEGGER_STOP_Limit_PSP,應該實現并調用__SEGGER_STOP_X_InitLimits。

使用SEGGER鏈接器,運行時初始化代碼將自動調用__SEGGER_STOP_X_InitLimits:

initialize bycalling __SEGGER_STOP_X_InitLimits { section .data.stop.* };

使用GNU鏈接器時,應該在main中的開始位置調用__SEGGER_STOP_X_InitLimits

int main(void) {
  int NumItems;
 
 #if !defined (__SEGGER_LINKER)
  //
  // Optionally initialize stack limits if not done by runtime init.
  //
  __SEGGER_STOP_X_InitLimits();
 #endif
 ...
}

在運行初始化之前調用函數

當系統在運行初始化之前調用函數時,Cortex-M上默認在Reset_Handler中調用SystemInit, __SEGGER_STOP_Limit_MSP應設置為0,以禁用堆棧檢查。

Reset_Handler:
    .extern __SEGGER_STOP_Limit_MSP
    //
    // Initialize main stack limit to 0 to disable stack checks before runtime init
    //
    movs  R0, #0
    ldr   R1, =__SEGGER_STOP_Limit_MSP
    str   R0, [R1]
    //
    // Call SystemInit
    //
    bl   SystemInit
    ...

使用RTOS

當使用RTOS或其他多任務機制時,任務切換程序必須在切換堆棧時更新堆棧上限變量(通常為__SEGGER_STOP_Limit_PSP)。

ChangeTask:
  ...
  ldr   r0, [r1, #0]  // OS.pCurTask
  ldr   r3, [r0, #8]  // OS.pCurTask->pStackBottom
  add   r3, #100    // Buffer before stack overflow
  ldr   r2, =__SEGGER_STOP_Limit_PSP
  str   r3, [r2]    // Update stack limit
   ...

建議對所有任務啟用堆棧檢查。RTOS可以通過將limit變量設置為0來禁用某些任務的堆棧檢查。

堆棧溢出幾乎在每個系統中都可能遇到。Embedded Studio提供了使用示例,展示簡單系統和多任務系統的堆棧溢出行為及處理。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5343

    瀏覽量

    120377
  • RTOS
    +關注

    關注

    22

    文章

    813

    瀏覽量

    119643
  • 編譯器
    +關注

    關注

    1

    文章

    1634

    瀏覽量

    49133
  • 緩存器
    +關注

    關注

    0

    文章

    63

    瀏覽量

    11661
收藏 人收藏

    評論

    相關推薦

    Embedded Studio堆棧溢出預防功能

    為了識別運行的嵌入式系統中的堆棧溢出問題,SEGGER編譯器通過為每個函數生成檢測代碼的方式來檢查堆棧溢出。該功能可以使用命令行開關-mstack-overflow-check來使能。
    發表于 07-14 11:08 ?618次閱讀

    什么是堆棧溢出?如何分配堆棧空間大小?

    前些日子bug交流群里的小哥調試了一個堆棧溢出的bug,動不動數據就被篡改了,應該也是搞得焦頭爛額,頭皮發麻!當時bug菌看了下,于是拋出了自己的一些調試經驗,一般這樣的問題80%是越界和堆棧
    的頭像 發表于 11-08 09:52 ?4557次閱讀
    什么是<b class='flag-5'>堆棧</b><b class='flag-5'>溢出</b>?如何分配<b class='flag-5'>堆棧</b>空間大小?

    freertos與STM32如何分配堆棧空間

    freertos與STM32分棧、堆、全局區、常量區、代碼區、RAM、ROM,及如何分配堆棧空間基于STM32分棧、堆、全局區、常量區、代碼區、RAM、ROM FreeRTOS任務棧大小確定及其
    發表于 08-03 06:36

    FreeRTOS中的任務堆棧溢出檢測機制

    在FreeRTOS中,每個任務都擁有自己的堆棧,該堆棧的大小由創建任務時xTaskCreate函數的函數參數所決定。但當任務所使用的堆棧空間超出分配給它的空間時,則會發生堆棧
    發表于 10-15 13:51

    如何在Embedded Studio中使用RTT?

    Embedded Studio是SEGGER微控制器的多平臺IDE,包含了專業嵌入式C和C++編程和開發所需的所有工具和功能。結合基于Clang、高度優化的C/C++ SEGGER編譯器,可以生成
    發表于 02-17 14:25

    SEGGER Embedded Studio下載激活

    先楫半導體非常nice的是,他們和SEGGER達成了合作,可以讓開發者免費使用SEGGER Embedded Studio,包括商用哦。 1.SEGGER Embedded Studio
    發表于 05-25 16:23

    在SEGGER Embedded Studio對E203使用NMSIS DSP報錯,Embedded Studio應該如何配置?

    模仿embedded_studio_project中dsp_demo中的配置,希望在Embedded Studio中也使用Hbird SDK中的DSP庫 但是最后會報這樣的錯誤,好像是因為DSP
    發表于 08-12 06:02

    MSP430 C語言編程的程序堆棧溢出分析

    MSP430 C語言編程的程序堆棧溢出分析
    發表于 05-16 15:04 ?40次下載

    網絡安全中的堆棧溢出技術解析

    網絡安全日益為人們所重視,其關鍵就是緩沖溢出問題,幾乎所有的操作系統都避免不了緩沖溢出漏洞的威脅。網絡安全中的堆棧溢出技術是一種含量較高的計算機技術。本文用
    發表于 08-26 10:46 ?14次下載

    鼠標HID例程(中)

    鼠標 HID 例程 緊接《鼠標 HID 例程(上)》一文,繼續向大家介紹鼠 標 HID 例程的未完的內容。
    發表于 07-26 15:18 ?0次下載

    cad堆棧溢出的原因及解決方式

    近期有用戶反饋在打開AutoCad 2007的時候頻繁出現卡死的情況,并提示還提示0x00000FD堆棧溢出,重啟電腦和重裝軟件都無法解決。針對該問題小編整理了一些方法供大家參考。
    發表于 11-28 14:19 ?2.8w次閱讀
    cad<b class='flag-5'>堆棧</b><b class='flag-5'>溢出</b>的原因及解決方式

    關于堆棧溢出技術你知道多少?

    雖然溢出在程序開發過程中不可完全避免,但溢出對系統的威脅是巨大的,由于系統的特殊性,溢出發生時攻擊者可以利用其漏洞來獲取系統的高級權限root,因此本文將詳細介紹堆棧
    的頭像 發表于 07-04 16:42 ?6392次閱讀

    CrossCore Embedded Studio集成開發環境的介紹

    這是新的CrossCore? Embedded Studio (CCES)集成開發的簡要說明。CrossCore? Embedded Studio是針對ADI公司Blackfin?和S
    的頭像 發表于 07-10 06:08 ?3936次閱讀

    EE-372:CrossCore?Embedded Studio 1.1.x入門

    EE-372:CrossCore?Embedded Studio 1.1.x入門
    發表于 05-15 18:43 ?10次下載
    EE-372:CrossCore?<b class='flag-5'>Embedded</b> <b class='flag-5'>Studio</b> 1.1.x入門

    STM32 堆棧溢出檢測

    釋放,存放函數調用,局部變量等數據。堆heap用于動態內存分配。堆棧可以在啟動文件或者鏈接腳本中指定大小,但在實際開發中,尤其工程量較大的項目中難以確定堆棧使用量,容易造成堆棧溢出,造
    發表于 12-27 18:32 ?22次下載
    STM32 <b class='flag-5'>堆棧</b><b class='flag-5'>溢出</b>檢測
    主站蜘蛛池模板: 日本精品三级| 狠狠婷婷| 丁香花在线电影小说观看| 手机看片日韩在线| 中年艳妇乱小玩| 色在线播放| 国产r67194吃奶视频| 国内精品久久久久久久久野战 | 午夜影院h| 六月丁香啪啪| 色香蕉在线视频| 在线观看深夜观看网站免费| 免费在线看视频| 色视频在线观看免费| 夜夜春夜夜夜夜猛噜噜噜噜噜| 日本sese| 三级毛片在线看| 天天躁夜夜躁狠狠躁躁| 色女人综合| 免费人成黄页在线观看日本| 欧美黄色片在线播放| 成人国产三级精品| 久久国产精品免费网站| 久久15| 亚洲丁香| 操你啦在线视频| 在线观看免费视频一区| 你懂的在线免费视频| 日本加勒比黑人| 亚洲高清免费观看| 亚洲禁片| 主人扒开腿揉捏花蒂调教cfh| 国产色系视频在线观看免费| 2019国产情侣| 奇米久草| 高清一本之道加勒比在线| 四级毛片在线播放| 天天狠操| 亚洲第二色| 天天爽夜夜爽一区二区三区| 在线成人免费|