嵌入式軟體中的棧溢位檢查

2021-10-03 07:50:09 字數 1001 閱讀 3748

我們在編寫嵌入式軟體的時候,經常會遇到棧溢位的問題。這種棧溢位產生的原因有下面兩種。

一種是正常棧區空間不足,在函式巢狀過深,區域性變數過多時,會導致棧空間不足。特別是有os的嵌入式**中,task的棧區通常被定義為記憶體段或者全域性陣列,這種情況下棧區空間被限制在陣列或者記憶體段的上下邊界,一旦巢狀過深,則堆疊溢位。

第二種是**錯誤導致的棧區溢位。比方說錯誤的指標、不加邊界檢查的陣列訪問等會造成這種情況。

這兩種棧區溢位都會產生宕機或者**跑飛的風險。當棧區溢位時,棧指標指向非法區域,這個區域有可能是 全域性變數區,有可能是別的task的棧區, 總之,這種區域的用途不確定而且很有可能會被其他**改寫從而造成棧幀不正確導致**不能正常返回。

所以根據棧溢位產生的原因,擬定兩種不同的檢查方案。

第一種 方案:根據函式巢狀過程中棧指標的變化如下:

比如說b函式中對c的訪問越界,就會造成pc被修改,在退棧時,函式就會跳轉到未知的pc值從而導致**執行異常,這種情況下,如果我們能在a呼叫b時,在pc後面插入一段空白記憶體,並初始化為特定值,在b函式執行結束後,對該區域的值進行檢查。這樣一旦這個值被改寫,則可判定為棧溢位。當然這種值的新增無法在**中實現,因為c封裝了彙編的細節。只能通過修改編譯器來實現這種功能,而且這種功能只能識別一部分的溢位,像修改了其他的位置,則無法識別。可喜的是,已經有編譯器實現了這種功能,比方說rh850的編譯器。

第二種方案:

針對task棧區溢位的問題,操作思路和函式內部溢位問題一致,在定義task並初始化棧空間時。在棧區的頂部和底部留白,並初始化為特定值,在任務切換時,對該值進行檢查。一旦該值被異常改寫,則證明棧空間溢位。這種方法能識別大多數棧空間溢位的問題,缺點是需要消耗少量的cpu時間,不過我認為是值得的。許多商用os都追加了這種功能,比如autosar帶的os,ri850之類的車規os。

值型別的顯示 隱式轉換和算術溢位檢查

顯示 隱式 轉換 編譯器能夠在基元型別之間進行隱式或顯示轉換 int32 i 5 int64 l i 從int32到int64的隱式轉換 如果兩個型別之間的轉換是 安全 的 安全是指轉換不會造成資料丟失 那麼c 允許在他們之間進行隱式轉換 如果轉換存在潛在的 安全 轉換會引起丟失精度或數量級 c 要...

關於嵌入式中的堆與棧

這是我在網上看的一篇文章,感覺不錯 一 預備知識 程式的記憶體分配 由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放,存放函式的引數值,區域性變數等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放 malloc free ne...

學習嵌入式軟體的歷程

要說我的嵌入式歷程,還要從去年 11月份開始,因為在研究生開了一門接 術課程,再加上本科學習了 51系列微控制器的基本原理,所以想找乙份這方面的兼職歷練自己。到了週末,我就跑人才招聘會投簡歷去。由於工作經驗的匱乏,很少合適的崗位選擇。跑了幾次,得到了乙個面試,應聘微控制器硬體方面的吧,人家問我,懂不...