1. gzyueqian
      18078865874

      嵌入式開發(fā):創(chuàng)建堆棧監(jiān)視器的7個(gè)步驟

      更新時(shí)間: 2022-04-28 11:18:35來(lái)源: 粵嵌教育瀏覽量:9455

        在嵌入式系統(tǒng)中尋找最痛苦的錯(cuò)誤之一是堆棧溢出其邊界并開始覆蓋附近的內(nèi)存區(qū)域。堆棧溢出的癥狀通常在發(fā)生完美的中斷和函數(shù)調(diào)用風(fēng)暴時(shí)隨機(jī)出現(xiàn),這導(dǎo)致它們難以檢測(cè)。為了通過(guò)使用堆棧監(jiān)視器來(lái)防止堆棧溢出,嵌入式開發(fā)人員可以采取七個(gè)步驟來(lái)確保堆棧保留在其分配的內(nèi)存區(qū)域中。

        步驟 1 – 執(zhí)行最壞情況堆棧分析

        許多編譯器和工具鏈會(huì)自動(dòng)將堆棧大小設(shè)置為 0x400 字節(jié),相當(dāng)于一千字節(jié)的 RAM。對(duì)于許多應(yīng)用程序來(lái)說(shuō),一千字節(jié)的堆棧大小通常就足夠了,但這是計(jì)算機(jī)科學(xué)而不是猜謎游戲,那么工程師如何確保堆棧大小合適呢?答案是執(zhí)行最壞情況堆棧分析。

        最壞情況堆棧分析可以通過(guò)許多不同的方式執(zhí)行,超出了本文的范圍。一般來(lái)說(shuō),開發(fā)人員有許多項(xiàng)目需要完全理解。首先,有必要了解其應(yīng)用程序的調(diào)用深度;有多少函數(shù)正在調(diào)用在返回鏈之前調(diào)用函數(shù)的函數(shù)。每個(gè)返回地址都存儲(chǔ)在堆棧中。其次,開發(fā)人員需要了解這些函數(shù)中每個(gè)變量的數(shù)量和大小,以估計(jì)每個(gè)函數(shù)將使用多少堆棧空間。最后,嵌入式開發(fā)人員需要確定可以同時(shí)觸發(fā)多少個(gè)中斷以及每個(gè)中斷幀的大小。

        步驟 2 – 設(shè)置堆棧大小

        最壞情況堆棧分析的輸出將導(dǎo)致堆棧的大小。盡管對(duì)系統(tǒng)進(jìn)行了仔細(xì)分析,但計(jì)算堆棧大小可能很困難且很難做到,將最終數(shù)字乘以 1.5 并沒(méi)有什么壞處,只是為了確保包含一個(gè)合理的緩沖區(qū)以應(yīng)對(duì)不可預(yù)見的情況。然后可以通過(guò)項(xiàng)目屬性或鏈接器文件更改堆棧大小,具體取決于首選項(xiàng)和工具功能。

        步驟 3 – 選擇一種保護(hù)方法

        正確調(diào)整堆棧大小是防止堆棧溢出和破壞附近內(nèi)存區(qū)域的良好進(jìn)展,但它仍然不允許檢測(cè)此類溢出事件。在嵌入式系統(tǒng)中,有多種方法可以檢測(cè)到此類事件。首先,是使用內(nèi)存保護(hù)單元并設(shè)置堆棧的邊界,以便如果堆棧越過(guò)邊界,則會(huì)觸發(fā)中斷,然后系統(tǒng)可以記錄問(wèn)題并按照程序恢復(fù)系統(tǒng)。其次,如果正在使用 RTOS,開發(fā)人員可以啟用堆棧溢出檢測(cè)。默認(rèn)情況下,許多 RTOS 都啟用了此檢測(cè),但我看到有文章建議關(guān)閉此功能以提高性能!不建議開發(fā)人員禁用堆棧溢出檢測(cè),否則你可能會(huì)感到堆棧溢出錯(cuò)誤的冷落。最后,在沒(méi)有 MPU 或使用 RTOS 的資源受限系統(tǒng)中,開發(fā)人員可以非常輕松地創(chuàng)建自己的堆棧監(jiān)視器。

        步驟 4 – 將保護(hù)部分添加到鏈接器

        嵌入式開發(fā)人員可以通過(guò)多種不同的方式創(chuàng)建堆棧保護(hù)部分,但指定保護(hù)大小和位置的一種有用方法是使用鏈接器文件。可以更新鏈接器文件以包含保護(hù)大小和位置。大小是完全任意的。一個(gè)經(jīng)驗(yàn)法則是讓它足夠大,這樣如果發(fā)生溢出,它就不會(huì)溢出防護(hù)區(qū)域。在圖 1 中可以看到保護(hù)部分的示例。

        圖1

        步驟 5 – 使用模式填充保護(hù)空間

        創(chuàng)建保護(hù)部分很棒,但除非其中填充了已知模式,否則它并不是非常有用。然后可以稍后由應(yīng)用程序代碼檢查保護(hù)模式。任何模式都可以放置在防護(hù)區(qū)域中,但我發(fā)現(xiàn)使用人類可讀的模式很有用。使用 0xC0DE 模式是我最喜歡使用的模式之一。圖 1 顯示了一個(gè)人口密集的警戒區(qū)域的示例。確切的實(shí)現(xiàn)將根據(jù)所使用的工具鏈而有所不同。

        步驟 6 – 定期檢查模式

        應(yīng)用程序代碼應(yīng)設(shè)置為定期檢查整個(gè)保護(hù)部分是否仍然包含正確的模式。模式的變化將由堆棧溢出引起。此檢查的應(yīng)用程序代碼相對(duì)簡(jiǎn)單。嵌入式開發(fā)人員只需要遍歷每個(gè)模式并驗(yàn)證它是否仍然正確。圖 2 顯示了一個(gè)使用指針檢查堆棧保護(hù)填充模式的示例循環(huán)。如果檢測(cè)到更改,則應(yīng)用程序可以分支并嘗試記錄系統(tǒng)堆棧并開始恢復(fù)過(guò)程。

        圖2

        步驟 7 – 測(cè)試警衛(wèi)

        創(chuàng)建堆棧監(jiān)視器的最后一步當(dāng)然是測(cè)試它!測(cè)試它的最佳方法之一是編寫一小段代碼來(lái)修改堆棧保護(hù)模式。堆棧保護(hù)的定期檢查應(yīng)該檢測(cè)到模式已經(jīng)改變,這表明堆棧已經(jīng)溢出。

        經(jīng)過(guò)測(cè)試的堆棧監(jiān)視器對(duì)提高系統(tǒng)的可靠性和穩(wěn)健性大有幫助。一旦監(jiān)控的堆棧能夠檢測(cè)到溢出,就需要額外的應(yīng)用程序代碼來(lái)決定如何處理該信息。記錄調(diào)用深度、寄存器值和應(yīng)用程序狀態(tài)將幫助開發(fā)人員重復(fù)溢出并發(fā)現(xiàn)根本原因。

        結(jié)語(yǔ)

        開發(fā)人員在開始軟件開發(fā)時(shí)經(jīng)常會(huì)忽略堆棧。堆棧溢出是難以發(fā)現(xiàn)的錯(cuò)誤之一,除非嵌入式開發(fā)人員努力對(duì)其進(jìn)行監(jiān)控。檢測(cè)堆棧溢出并不困難,監(jiān)視器的輕微性能損失非常值得!


      免費(fèi)預(yù)約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 亚洲午夜成人不卡在线 | 亚洲v精品V无:码一区二区桃花 | 亚洲欧美在线视频播放 | 一级国产加日韩加欧美 | 亚洲欧洲中文日韩AV乱 | 亚洲欧美综合久久久 |