0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MCUXpresso IDE的棧分析功能

恩智浦MCU加油站 ? 來源:恩智浦MCU加油站 ? 2023-05-26 09:35 ? 次閱讀

嵌入式系統(tǒng)中,RAM 的大小是非常有限的。尤其是做器件選型時,更小 RAM 的芯片意味著更低的采購價格,產(chǎn)品才會更具競爭力,有更高的毛利。

在這樣極致的壓榨下,留給堆棧的空間更加少了。開發(fā)者不得不面對爆棧的巨大風(fēng)險。每個軟件工程師都想有一個工具能夠幫助他們檢驗(yàn)棧的使用情況,從而很好的評估風(fēng)險。

人們尋常采用的方法是把棧里都先寫滿一個特定的值,比如 0xAA。隨后在程序運(yùn)行一段時間之后看看還剩多少 0xAA 沒有被改掉。這種方法確實(shí)有一定的效果,但是顯然還不夠直觀,又比較麻煩。尤其是當(dāng)工程有不止一個棧的時候。

為此,新版本的 gcc 編譯器提供了一個有用的編譯選項(xiàng)-fstack-usage。使用這個選項(xiàng)后,編譯器會額外產(chǎn)生有關(guān)棧使用情況的信息,而 MCUXpresso 可以整理這些信息,并將它們非常清晰地顯示出來。

fstack-usage與Call Graph

先讓我們看看 GNU 關(guān)于-fstack-usage 的說明:(https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html)

7d02d5e8-fafa-11ed-90ce-dac502259ad0.png

它以每個函數(shù)為基礎(chǔ),使編譯器生成程序的堆棧使用信息。信息存放在后綴名為.su 的文件中。

下圖是編譯文件夾的內(nèi)容,可以看到有一個同名的 su 文件。

7d0b6e9c-fafa-11ed-90ce-dac502259ad0.png

這個文件的內(nèi)容也很簡單,它列 出 了 文 件名(system_MIMXRT1052.c), 函數(shù)的 行號和列號, 函數(shù)的名稱, 如 SystemInit,堆棧的使用情況(8),以及如何分配(static)。

7d14b60a-fafa-11ed-90ce-dac502259ad0.png

但是這樣單個顯示是沒有什么參考價值的,我們需要的是整個工程的全景,要把所有的 su 文件整理出來。 MCUXpresso IDE v11 版本提供了這一功能。在 Image Info 窗口中有一個 Call Graph 標(biāo)簽。單擊右上角的導(dǎo)入按鈕就可以導(dǎo)入當(dāng)前整個工程的 stack 使用情況。

7d1f7afe-fafa-11ed-90ce-dac502259ad0.png

前面帶“>”的函數(shù)名稱顯示“根”函數(shù):它們不能被從其他任何地方調(diào)用的。其中ResetISR就是 reset 入 口 函 數(shù) , 而 exception handlers 里 面 都 是 中 斷 服 務(wù) 程 序 。
HAL_UartReceiveBlocking()函數(shù)因?yàn)闆]有其它函數(shù)顯式的調(diào)用它,所以也被認(rèn)為是根函數(shù)。
這里我們可以看到這種分析的一個弱點(diǎn),如果函數(shù)是通過函數(shù)指針的方式來調(diào)用那么該功能就無能為例了。但是使用者可以自己分析程序給續(xù)上。

如果函數(shù)是遞歸的,則用一個特殊的雙箭頭標(biāo)記。成本估算將針對單級遞歸。

Full Cost 表示累積堆棧使用量(此函數(shù)加上所有被調(diào)用的)。

Local Cost 表示本層的堆棧使用量。

Depth 表示由該函數(shù)引起的調(diào)用級別數(shù)。

請注意Exception Handlers 這里,它集中了所有的中斷服務(wù)程序。由于沒有顯式的調(diào)用,它們都是根函數(shù),并且這里只統(tǒng)計(jì)非中斷嵌套情況下的最大用量。所以如果允許中斷嵌套, 那么對于棧的分配應(yīng)該更加保守。

此外,如果函數(shù)是用匯編語言寫的,那么工具是無法統(tǒng)計(jì)它們的棧使用情況, 一律會統(tǒng)計(jì)成‘4’。但如果調(diào)用到了其它函數(shù),深度和 Full cost 還是會被統(tǒng)計(jì)的。

需要注意這個堆棧使用報告僅涵蓋每個函數(shù)或調(diào)用樹的堆棧使用情況。它們不包括異常處理程序所需的額外堆??臻g。所以最后的堆棧計(jì)算是 ResetISR 棧+中斷棧,如果允許中斷嵌套,那么整個中斷嵌套最長的情況必須要被考慮。 該工具在基于 RTOS(例如 FreeRTOS)的系統(tǒng)中同樣運(yùn)行良好且開箱即用。因此,使用該工具,我們可以很好地估計(jì)每個任務(wù)堆棧的使用情況。棧計(jì)算可以使用下圖,它來自 Joseph Yiu,一位來自 ARM 的大牛。

7d2b3740-fafa-11ed-90ce-dac502259ad0.png

其它同棧保護(hù)有關(guān)的編譯選項(xiàng)

GCC 除了提供 stack-usage 這個編譯選項(xiàng)外,還有其它一些相關(guān)的選項(xiàng)可供選擇。

- Wstack-usage

這是一個有用處的編譯選項(xiàng):-Wstack-usage。它能夠在堆棧使用超過限制時產(chǎn)生 warning

信息。用法是:

-Wstack-usage=256

它表示如果棧使用量超過 256 時產(chǎn)生警告。這樣就能更快速地知道哪個函數(shù)超了。只說它有些用處而不是非常有用是因?yàn)椋会槍蝹€函數(shù)的堆棧用量, 不會按調(diào)用樹累計(jì)被調(diào)用函數(shù)的堆??倲?shù)。

- fstack-protector 這個選項(xiàng)的解釋是: 產(chǎn)生額外的代碼來檢查緩沖區(qū)溢出,例如堆棧粉碎攻擊。這是通過向具有易受攻擊對象的函數(shù)添加保護(hù)變量來實(shí)現(xiàn)的。這包括調(diào)用 alloca 的函數(shù),以及緩沖區(qū)大于 8 字節(jié)的函數(shù)。在輸入函數(shù)時初始化保護(hù),然后在函數(shù)退出時檢查保護(hù)。如果保護(hù)檢查失敗,將打印錯誤消息,程序退出。

- fstack-protector-all

同-fstack-protector 基本相同, 區(qū)別是它為所有的函數(shù)都提供保護(hù)。

-fstack-protector和-fstack-protector-all在ebp和ip等信息的地址下面放一個保護(hù)數(shù), 如果棧溢出 ,那么這個 32 位數(shù)會被修改,就會導(dǎo)致函數(shù)進(jìn)入棧溢出錯誤處理函數(shù)。一旦檢測到溢出就會調(diào)用__stack_chk_fail()函數(shù)。這個函數(shù)需要用戶自己來寫,比如可以打印一個報錯信息,或者執(zhí)行其它一些保護(hù)措施。 下圖是在編譯選項(xiàng)里加入-fstack-protector-all 后一個普通C函數(shù)的匯編內(nèi)容。

7d3318f2-fafa-11ed-90ce-dac502259ad0.png

當(dāng)然,可以想見,如果每個函數(shù)都加這么一段,編譯出來的二進(jìn)制文件會大上許多,執(zhí)行速度也會變慢一些。而如果僅僅使用-fstack-protector,則很少有函數(shù)會被保護(hù)。因?yàn)?alloca() 是在棧(stack)里面分配空間,而我們一般都是用 malloc()在堆(heap)里面分配。

小結(jié)

棧空間防溢出是軟件設(shè)計(jì)中非常關(guān)鍵的問題。MCUXpresso IDE 的 Call Graph 窗口為開發(fā)者提供了很好的可視化統(tǒng)計(jì)表格, 非常便于對堆棧使用情況的評估。論程序有沒有操作系統(tǒng),它都非常有效。 而GCC編譯器提供的其它一些選項(xiàng),雖然也有用處,但是在嵌入式軟件設(shè)計(jì)中還是用在 debug 階段會更好一些。開發(fā)者還是應(yīng)該盡量使用 call Graph 功能做到事先防范。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    16667

    瀏覽量

    347806
  • 恩智浦
    +關(guān)注

    關(guān)注

    14

    文章

    5788

    瀏覽量

    104729
  • IDE
    IDE
    +關(guān)注

    關(guān)注

    0

    文章

    334

    瀏覽量

    46540
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1602

    瀏覽量

    48896
  • mcuxpresso
    +關(guān)注

    關(guān)注

    1

    文章

    38

    瀏覽量

    4116

原文標(biāo)題:MCUXpresso IDE 的棧分析功能

文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    MCUXpresso IDE 11.6.0增加功耗分析功能

    對于IOT 物聯(lián)網(wǎng)的應(yīng)用,對于功耗要求越來越高,因此如果有軟件工具能集成功耗分析,對于代碼優(yōu)化以及產(chǎn)品性能提升是有極大幫助,在MCUXpresso IDE 11.6.0里面就集成了功耗分析
    發(fā)表于 11-17 10:15 ?489次閱讀

    MCUXpresso IDE怎么使用?

    為什么NXP的跨界 RT單片機(jī)沒有什么人用?教程也非常少。在外面其實(shí)很多人用的。 使用MCUXpresso IDE就更少。我不是開發(fā)技術(shù)。我是做產(chǎn)品設(shè)計(jì)的。先了解一下怎么回事。希望大家指教。1
    發(fā)表于 01-12 06:14

    MCUXpresso IDE在啟動調(diào)試會話時崩潰怎么修復(fù)?

    MCUXpresso IDE v10.2.1 [Build 795] [2018-07-25] MCUXpresso IDE在啟動調(diào)試會話時崩潰。錯誤對話框指出發(fā)生了堆棧錯誤。有人可以
    發(fā)表于 03-15 08:47

    MCUXpresso IDE中是否有延遲功能?

    我只是想知道 MCUXpresso IDE 中是否有延遲功能。例如,我想在我的程序中創(chuàng)建一個 1 秒的延遲,我想知道是否有一個很好的函數(shù)可以用來代替創(chuàng)建嵌套的 for 循環(huán)。 例如,在 Arduino 代碼中,我只使用函數(shù):延遲
    發(fā)表于 03-16 07:58

    如何將示例項(xiàng)目導(dǎo)入MCUXpresso IDE

    你好我是 MCUXpresso IDE 的新手。我已經(jīng)安裝了最新版本。當(dāng)我為演示板 RT1020 選擇示例時,沒有電機(jī)控制示例 (mc_pmsm)。我在 MCUXpresso 中嘗試
    發(fā)表于 03-16 08:15

    如何在MCUxpresso IDE的外設(shè)中配置USB?

    我必須在 MCUxpresso IDE 中使用 LPC54113 實(shí)現(xiàn) USB 協(xié)議代碼。請?zhí)峁┮韵略敿?xì)信息,1. 如何在 MCUxpresso IDE 的外設(shè)中配置 USB。2.US
    發(fā)表于 04-04 06:22

    如何為pn7362使用MCUXpresso IDE?

    我想使用 PN7362 芯片實(shí)現(xiàn) NFC 功能。但是,如果安裝MCUXpresso IDE 搜索SDK,則沒有PN7362 的SDK。 我不知道如何在 MCUXpresso
    發(fā)表于 04-23 06:56

    MCUXpresso工具套件啟動和運(yùn)行

    RT開發(fā)硬件,與會者將直觀地了解如何構(gòu)建自定義的SDK、配置引腳和時鐘設(shè)置、生成項(xiàng)目、導(dǎo)入和調(diào)試應(yīng)用,并了解MCUXpresso IDE的高級調(diào)試功能,包括追蹤、分析、覆蓋、觀察點(diǎn)等
    的頭像 發(fā)表于 01-16 07:00 ?4925次閱讀
    <b class='flag-5'>MCUXpresso</b>工具套件啟動和運(yùn)行

    MCUXpresso IDE在Flash調(diào)試的注意事項(xiàng)

    大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是 MCUXpresso IDE 下使用 J-Link 下載算法在 Flash 調(diào)試注意事項(xiàng)。 介紹一下如何使用新生成的 flash
    的頭像 發(fā)表于 12-23 13:53 ?923次閱讀

    痞子衡嵌入式:MCUXpresso IDE下在線調(diào)試時使用不同復(fù)位策略的現(xiàn)象總結(jié)

      大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家分享的是MCUXpresso IDE下在線調(diào)試時使用不同復(fù)位策略的現(xiàn)象總結(jié)?! ”酒獙?shí)際上是《IAR在線調(diào)試時設(shè)不同復(fù)位類型可能會導(dǎo)致
    發(fā)表于 11-30 18:06 ?14次下載
    痞子衡嵌入式:<b class='flag-5'>MCUXpresso</b> <b class='flag-5'>IDE</b>下在線調(diào)試時使用不同復(fù)位策略的現(xiàn)象總結(jié)

    使用Eclipse和MCUXpresso IDE調(diào)試RV32M1-VEGA RISC-V開發(fā)板

    使用Eclipse和MCUXpresso IDE調(diào)試RV32M1-VEGA RISC-V開發(fā)板
    發(fā)表于 12-06 20:06 ?7次下載
    使用Eclipse和<b class='flag-5'>MCUXpresso</b> <b class='flag-5'>IDE</b>調(diào)試RV32M1-VEGA RISC-V開發(fā)板

    MCUXpresso IDE下工程鏈接文件配置管理與自動生成機(jī)制介紹

    我們知道不同 IDE 下鏈接文件語法是不一樣的,而恩智浦 MCUXpresso IDE 底層編譯器是 Arm GCC,因此其鏈接文件就是標(biāo)準(zhǔn) GCC 下 .ld 文件。
    的頭像 發(fā)表于 11-17 10:41 ?2930次閱讀
    <b class='flag-5'>MCUXpresso</b> <b class='flag-5'>IDE</b>下工程鏈接文件配置管理與自動生成機(jī)制介紹

    MCUXpresso IDE下生成鏡像文件的方法及其與IAR,MDK差異

    MCUXpresso IDE下生成鏡像文件的方法及其與IAR,MDK差異
    的頭像 發(fā)表于 09-28 17:05 ?747次閱讀
    <b class='flag-5'>MCUXpresso</b> <b class='flag-5'>IDE</b>下生成鏡像文件的方法及其與IAR,MDK差異

    MCUXpresso IDE下將源碼制作成Lib庫方法及其與IAR,MDK差異

    MCUXpresso IDE下將源碼制作成Lib庫方法及其與IAR,MDK差異
    的頭像 發(fā)表于 11-07 17:13 ?1009次閱讀
    <b class='flag-5'>MCUXpresso</b> <b class='flag-5'>IDE</b>下將源碼制作成Lib庫方法及其與IAR,MDK差異

    如何在MCUXpresso IDE中測量能耗?

    如何在MCUXpresso IDE中測量能耗?
    的頭像 發(fā)表于 09-19 16:40 ?461次閱讀
    如何在<b class='flag-5'>MCUXpresso</b> <b class='flag-5'>IDE</b>中測量能耗?