王正鋒 李紀波


摘 要發動機控制軟件多任務程序運行時,共享變量的處理容易發生數組訪問越界、除零、數據溢出等錯誤,從而造成異常的后果。采用動態測試的方法檢測此類錯誤成本大、效率低。本文借助PolySpace測試工具,模擬軟件動態運行時的行為,使用靜態驗證的方法有效檢測可能發生的運行時錯誤,更高效地發現多任務程序中的缺陷。
【關鍵詞】多任務 運行時錯誤 靜態測試 PolySpace
1 引言
航空發動機控制系統目前廣泛采用全權限數字電子控制系統(FADEC)。其中的控制軟件為高安全等級軟件,采用多中斷或者多任務的架構設計。在軟件的設計過程中,很可能會出現多個任務或中斷服務程序對共享變量進行操作的處理,對這處理的設計如果考慮不周全,很容易導致程序在運行過程中出現數組訪問越界、除零、負數開方、整數或浮點數據溢出等錯誤,產生預定義之外的不正確結果或者處理器異常復位等后果。
常規的測試手段對于上述程序運行時錯誤的檢測并不能起到很好的效果。使用PRQAC進行靜態分析可以檢查代碼的編程規范、分析程序的靜態結構,但是并不分析代碼的動態行為。在真實環境中執行動態測試,測試用例能夠覆蓋的場景有限,不一定能夠觸發錯誤發生,尤其對于偶爾才出現的問題,需要大量重復測試才可能發現。除此之外,動態測試能夠發現異常現象,但產生異常的原因還需要更多時間去定位,效率很低。
本文介紹了一種使用靜態驗證的手段檢測多任務程序運行時錯誤的方法,借助工具軟件PolySpace,模擬軟件動態運行時的行為,更高效地發現軟件缺陷。
2 測試原理
2.1 PolySpace的工作原理
PolySpace使用語義分析技術,它依靠大量的數學定理提供的規則去分析軟件的動態行為,基于變量的數值范圍和變量之間的關系、程序的控制結構、程序內部過程之間的關系(函數調用)、多任務分析等進行運行時錯誤的檢測。
其分析結果對程序運行時可能會出現問題的代碼實現,會給出橙色的告警標識以及可能引發錯誤的場景;對于肯定會出現問題的地方,會給出紅色告警和引發錯誤的場景;對于不會出現問題的部分,會給出綠色的標識。由于PolySpace分析驗證時計算出的變量范圍始終是實際運行時變量范圍的擴展集,所以分析的結果不會漏掉可能出現的錯誤。
根據給出的告警和場景,進一步通過人工分析和確認,最終定位問題。
2.2 多任務程序運行時錯誤的分析
在基本的語義分析基礎上,對于多任務分析,還有一些必備的條件和假設:
(1)main函數是可結束的,即結尾的“}”必須可達;不存在無限循環或者引起紅色告警的錯誤,這樣才能保證多任務入口函數可以開始分析。
(2)任務或者是中斷/線程列表,其函數原型必須為void func_name(void)的形式。
(3)main函數結束后,開始分析各任務或者入口函數,分析的時候不會限定任務或中斷服務程序運行的順序和優先級(不影響分析結果)。
(4)由于不能明確地構建任務的具體優先級,所以分析時會模擬所有可能的優先級順序。
如果要分析的源程序不滿足這些條件和假設,需要人工對程序進行修改以滿足要求,以便進行分析。另外,可以通過人工編寫樁函數來調用實際的任務程序,使多任務的分析更接近實際運行場景。
3 項目應用實踐
在某項目發動機控制軟件中,曾經出現過兩個任務對共享的數據結構進行操作,其中一個任務對數據結構中的元素進行除法運算,出現除零操作而導致程序運行異常的問題。以下內容將對問題進行描述,并介紹通過Polyspace進行多任務分析檢測出此問題的實踐。
3.1 軟件問題概述
某項目控制軟件中存在多個中斷處理程序,其中頻率量的采集處理在兩個定時任務中實現。5ms定時中斷任務中讀取計數值,優先級稍低的25ms任務將計數值當作除數,計算頻率量。如圖1所示。
軟件設計之初考慮到這個FreqBuff[0]可能為0,因此在做除法之前做了極小值保護(使FreqBuff > 1000)保護,防止由于其等于0而出現除0的情況。
但是5ms定時中斷優先級高于25ms中斷,如果由于時序原因,如果恰好在所做的除零保護之后,25ms任務被更高優先級的5ms定時任務打斷,FreqBuff[0]賦值為0,再回到25ms任務進行除以FreqBuff[0]的運算時將會出現除零的錯誤,軟件運行出現異常。問題示意如圖1所示。
此問題引發的異常表象,不是每次運行都會出現,即使出現該問題引發的異常,進行故障排查和原因定位也要耗費大量的時間和人力,同時對排故人員的能力和經驗要求也比較高。
如果在開發階段或分析審查階段就能找出這個問題,會節約很大成本。
3.2 借助Polyspace進行分析
進行多任務程序分析的總體執行步驟為:先初始化全局變量,然后分析main函數,main函數正常結束后分析多個任務程序的運行。
Polyspace不會自動識別需要分析哪些任務,需要對原代碼進行一些改造、打樁或編寫驅動程序來保證分析過程可以正常結束。
首先,對main函數進行改造。原代碼的main函數中存在一個無限循環,可以將循環中執行的函數拿到main函數外作為一個單獨的任務進行分析。這樣可以保證main函數能正常結束,且不會漏掉循環中執行的函數的分析,具體更改如圖2所示。
然后手動編制樁函數,調用要分析的多個任務程序。該項目中共有兩個定時器中斷和串口、AD采集、DMA應答、通訊中斷等多個中斷服務程序,僅考慮要分析的兩個定時中斷任務,它們的函數原型為VOID IsrTimer1(VOID) 和VOID IsrTimer2(VOID),符合能夠進行分析的條件,無需改動。自己建立一個C文件,如Poly_multitsk.c一起加入到工程中,手動編寫的驅動函數如圖3所示。
這樣的驅動函數可以模擬每個中斷服務函數被調用0次或者多次,且各任務相互之間可被打斷。
最后,對分析選項進行必要的配置。除了一些通用的配置選項,在Multitasking選項中,設置好要分析的多任務的任務入口函數,這里包括我們手動編寫的兩個驅動函數和之前從main函數中摘出的一個循環任務。配置完成,即可在服務器端進行分析。
3.3 查看結果和人工分析
分析結束,Polyspace會產生結果文件,可以很容易查看分析后給出的各類告警。對于前面提到的程序中存在的問題,分析結果中給出了橙色的告警指示,如圖4所示。
結果中會明確給出可能出現錯誤的代碼所在的函數和文件,而且點擊告警處,可顯示導致錯誤的操作和場景,即除法運算的右側操作數可能為0。然后進一步分析可能導致除數為0的原因,是在另一個優先級更高的中斷任務中將這里作為除數的全局變量賦為0。
上述內容是對某項目程序中已知存在的問題進行實際的分析和驗證,只對兩個任務的交叉運行進行分析來舉例說明。可根據實際情況分析更多的任務,模擬更多的任務運行模式進行分析。
4 總結
在項目開發階段或早期的測試階段,根據實際需要,對程序中的多任務進行分析,可以盡早的發現可能出現的運行時錯誤。這些自動分析產生的可能發生錯誤的告警,并不一定會在真實運行時發生,根據這些信息,結合實際代碼對告警的內容進行更進一步的人工確認和分析,直到找出問題的根本原因,是必不可少而且至關重要的工作。
借助Polyspace進行自動分析需要的準備工作和后續的人工分析確認,需要花費一定的時間,但相對于軟件使用和維護階段再去對這些運行時錯誤進行排查和定位,成本是很低的,效率也大大提高,是非常有效的檢測多任務程序中運行時錯誤的方法。
參考文獻
[1]劉春裕,王蕾.基于PolySpace的嵌入式軟件內存測試[J].電腦技術與技術,2010,6(01):85-87.
[2]PolySpace Products for C Users Guide:5-19.
作者單位
中國航發控制系統研究所 江蘇省無錫市 214063