天天看點

由于同僚設計的代碼發現了一些嚴重的BUG,遲遲得不到解決,影響了整個開發項目的結案。于是,我找他們要來了全部代碼,搭建開

作者:物聯網全棧開發

由于同僚設計的代碼發現了一些嚴重的BUG,遲遲得不到解決,影響了整個開發項目的結案。

于是,我找他們要來了全部代碼,搭建開發環境,親自幫他們分析并解決問題。

在解決了因為多個不同優先級中斷互相打斷以及IAR代碼優化而導緻了UART發送狀态機狀态死鎖的BUG之後,我又發現了他們代碼中的記憶體越界通路的問題。

在用JLINK調試代碼時,程式以極低的機率運作到死循環。

從call stack看到,進入死循環之前調用的函數為_iar_dlfree_21,據此判斷應該是記憶體的動态配置設定和釋放出現了問題。

從IAR的安裝目錄下找到了dlmalloc.c檔案,把它加入到IAR工程中,這樣就可以在free()函數中設定段點,機關運作程式,以詳細檢視變量狀态以及代碼行為。

通過malloc函數配置設定一段記憶體,除了可以使用的記憶體區域之外,還包括了4個位元組的prev_foot變量,記錄上一個記憶體塊的大小,4個位元組的head變量,記錄目前記憶體塊的大小,以及兩個标志位bit0、bit1,bit0表示上一個記憶體塊是否被使用,記為pinuse,bit1表示目前記憶體塊是否有使用,記為cinuse。

當記憶體塊未被使用時,資料區的内容為上一個記憶體塊以及下一個記憶體塊的位址,分别占用4個位元組。

在free函數的USAGE_ERROR_ACTION處設定狀态,當出現錯誤時,函數跳轉到此處,調入abort函數進入死循環。

分析發現,出現錯誤時,還在使用的程式塊的head被破壞,長度錯誤而且bit1的使用标志被清零,進而free函數在對釋放的記憶體塊合并時,判斷資料區的上一個記憶體塊位址錯誤,即ok_address(fm, F)為假,進而報錯。

應該是在通過malloc申請記憶體之後,對申請到的空間通路超出範圍,改寫了下一個記憶體塊的head變量。

緊接着我定義了一個環形數組,記錄下通過malloc配置設定的變量标号以及大小。

當發生錯誤時,從環形數組中找到使用與錯誤的記憶體塊相鄰的上一個記憶體塊的變量,從代碼中分析該變量的使用情況,發現在memcpy時長度超過了申請的記憶體大小,改變了出錯記憶體塊的head值。

由于同僚設計的代碼發現了一些嚴重的BUG,遲遲得不到解決,影響了整個開發項目的結案。于是,我找他們要來了全部代碼,搭建開
由于同僚設計的代碼發現了一些嚴重的BUG,遲遲得不到解決,影響了整個開發項目的結案。于是,我找他們要來了全部代碼,搭建開
由于同僚設計的代碼發現了一些嚴重的BUG,遲遲得不到解決,影響了整個開發項目的結案。于是,我找他們要來了全部代碼,搭建開

繼續閱讀