• 文章
  • 靜態程式碼分析
作者:
2012 年 3 月 12 日 (最後更新: 2012 年 3 月 12 日)

靜態程式碼分析

評分:3.4/5 (57 票)
*****
靜態程式碼分析是檢測軟體原始碼中的錯誤和缺陷的過程。

靜態分析可以被視為一種自動化的程式碼審查過程。現在,我們來談談程式碼審查。

程式碼審查是檢測缺陷最古老、最安全的方法之一。它涉及對原始碼進行聯合細緻的閱讀,並就如何改進程式碼提出建議。這個過程會揭示錯誤或可能在未來變成錯誤的 कोड 片段。人們還認為,程式碼的作者不應該解釋某個程式部分是如何工作的。程式執行演算法應該直接從程式文字和註釋中清晰地看出。如果不是這樣,程式碼就需要改進。

程式碼審查通常效果很好,因為程式設計師更容易發現別人程式碼中的錯誤,而不是自己程式碼中的錯誤。要了解更多關於程式碼審查方法的資訊,請參閱 Steve McConnell 的優秀著作《程式碼大全》[1]。

聯合程式碼審查方法唯一的重大缺點是價格極其高昂:您需要定期召集幾位程式設計師來審查新的程式碼,或者在對程式碼應用了推薦的更改後重新審查程式碼。程式設計師也需要定期休息,因為他們一次審查大量程式碼片段時注意力可能會迅速減弱,這樣程式碼審查就沒有意義了。

一方面,您希望定期審查程式碼。另一方面,這樣做成本太高。靜態程式碼分析工具是一種折衷的解決方案。它們可以不知疲倦地處理程式的原始碼文字,並向程式設計師提供關於他/她應該考慮哪些程式碼片段的建議。當然,程式永遠無法取代由程式設計師團隊進行的完整程式碼審查,但價效比使得靜態分析的使用成為許多公司正在採用的一種相當不錯的實踐。

靜態程式碼分析軟體解決的任務可以分為 3 類

  1. 檢測程式中的錯誤。我們將在後面詳細討論這一點。
  2. 關於程式碼格式的建議。一些靜態分析器允許您檢查原始碼是否符合您公司接受的程式碼格式標準。我們指的是控制各種構造中的縮排數量、空格/製表符的使用等等。
  3. 指標計算。軟體指標是一種度量,可以讓你獲得軟體或其規範的某個屬性的數值。有大量各種指標可以透過特定工具進行計算。

還有其他方法可以使用靜態程式碼分析工具。例如,靜態分析可以用作一種控制和培訓新員工的方法,這些員工還不熟悉公司的程式設計規則。

有許多商業和免費的靜態程式碼分析器。維基百科網站包含大量靜態分析器的列表:靜態程式碼分析工具列表。靜態程式碼分析器支援的語言列表也很長(C、C++、C#、Java、Ada、Fortran、Perl、Ruby 等)。

與任何其他錯誤檢測方法一樣,靜態分析有其優點和缺點。您應該明白,不存在理想的軟體測試方法。不同的方法將為不同的軟體類別產生不同的結果。只有結合各種方法才能實現軟體的最高質量。

靜態分析的主要優點是:它使您能夠大大降低消除軟體缺陷的成本。錯誤檢測得越早,修復它的成本就越低。因此,根據 McConnell 的《程式碼大全》一書中的資料,在測試階段修復錯誤的成本是在程式碼編寫階段修復錯誤的十倍。

修復缺陷的平均成本隨其產生和檢測時間的變化 圖 1. 修復缺陷的平均成本隨其產生和檢測時間的變化(表格資料來自 S. McConnell 的《程式碼大全》)。

靜態分析工具可以幫助您快速檢測大量的編碼階段錯誤,這大大降低了整個專案的開發成本。例如,PVS-Studio 靜態程式碼分析器可以在編譯完成後在後臺執行,並在存在潛在錯誤時告知程式設計師(請參閱增量分析模式)。

靜態程式碼分析的其他優點如下:
  1. 完全的程式碼覆蓋。靜態分析器甚至會檢查那些很少獲得控制的程式碼片段。這些程式碼片段通常無法透過其他方法進行測試。這使您能夠發現異常處理程式或日誌記錄系統中的缺陷。
  2. 靜態分析不依賴於您使用的編譯器以及編譯後的程式將執行的環境。它允許您找到可能幾年後才顯現出來的隱藏錯誤。例如,這些是未定義行為錯誤。此類錯誤可能在切換到其他編譯器版本或使用其他程式碼最佳化開關時發生。另一個隱藏錯誤的有趣例子在文章《記憶體覆蓋 - 為什麼?》中進行了討論。
  3. 您可以輕鬆快速地檢測出拼寫錯誤和複製貼上使用的後果。透過其他方法檢測這些錯誤通常是效率低下且浪費時間精力的事情。令人遺憾的是,您花費了一個小時進行除錯,結果卻發現錯誤是“strcmp(A, A)”之類的表示式。人們在討論典型錯誤時通常不記得這些麻煩。但實踐表明,檢測它們需要很長時間。

靜態程式碼分析的缺點
  1. 靜態分析通常在診斷記憶體洩漏和併發錯誤方面表現不佳。要檢測這些錯誤,實際上需要虛擬地執行一部分程式。這很難實現。此類演算法需要大量的記憶體和處理器時間。靜態分析器通常僅限於診斷簡單情況。檢測記憶體洩漏和併發錯誤更有效的方法是使用動態分析工具。
  2. 靜態分析工具會警告您一些奇怪的程式碼片段。這意味著程式碼實際上可能是正確的。這被稱為誤報。只有程式設計師才能理解分析器是否指向了真正的錯誤,或者僅僅是誤報。審查誤報的必要性會佔用工作時間,並削弱對真正包含錯誤的那些程式碼片段的注意力。

靜態分析器檢測到的錯誤多種多樣。例如,這裡是 PVS-Studio 工具中實現的診斷列表。一些分析器專注於某個特定領域或型別的缺陷,而另一些則支援特定的編碼標準,例如 MISRA-C:1998、MISRA-C:2004、Sutter-Alexandrescu Rules、Meyers-Klaus Rules 等。

靜態分析領域正在積極發展,新的診斷規則和標準不斷出現,而一些規則正在過時。因此,沒有必要嘗試基於它們可以檢測到的缺陷來比較分析器。比較工具的唯一方法是在一系列專案上測試它們並計算它們發現的真實錯誤的數量。這個主題在文章《比較程式碼分析器的困難,或者不要忘記可用性》中有詳細討論。

靜態程式碼分析檢測到的錯誤示例


關於靜態分析的誤解


參考文獻

  1. Steve McConnell,《程式碼大全,第二版》,Microsoft Press,平裝本,第二版,2004 年 6 月出版,914 頁,ISBN:0-7356-1967-0。
  2. Wikipedia。 靜態程式碼分析
  3. Coverity。《數十億行程式碼之後:使用靜態分析在現實世界中查詢 Bug》。
  4. 作者:Walter W. Schilling, Jr. 和 Mansoor Alam。《將靜態分析整合到軟體開發流程中》。
  5. 批評。Mark Dixon。《不使用靜態分析的五大理由》。