編寫安全可靠的程式碼:NASA「十個原則」的經驗教訓

Posted by Andylinee on Monday, June 5, 2023

“註:本文是透過 YouTube & Article Summary powered by ChatGPT 及 OpenAI 翻譯後編輯而成。”

影片:how NASA writes space-proof code


說明

作為軟體開發者,最糟糕的其中一種情況就是在正式環境的程式碼掛掉。但如果你的正式環境是外太空,反參照指標(null pointer dereference)、釋放後使用等問題可能導致衛星失去控制,隨之飄向無盡的虛空。為了避免這種情況,NASA 制定了一系列規則,重點是使他們的程式碼易於靜態分析。我將討論的規則實際上源自 NASA 稱之為「十個原則」的一組規則。一位 NASA 可靠的軟體開發者 Gerard Holzman 承認,其中一些規則有些嚴格,但在需要極高安全性的情境中,他認為這種權衡是值得的。NASA 將程式碼限制為簡單的控制流結構,這意味著他們不使用 goto 語句、set jumplong jump,也不使用遞迴(recursion)。遞迴或呼叫自身的函式會創造出非常難以理解的迴圈程式碼控制流程圖,遞迴程式碼可能導致運行失控,尤其在嵌入式系統中容易導致崩潰。


十個原則

原則一:簡單的控制流結構(imple Control Flow)

NASA 限制了一些結構的使用,如 goto 語句、set jumplong jump,以及遞迴。這些限制有助於避免複雜和難以理解的程式碼路徑,減少系統崩潰和運行失控的風險。

原則二:迴圈的固定上限(Limit All Loops)

為了防止無限迴圈和運行失控,NASA 對所有迴圈設定了固定的上限。即使在遍歷鏈結串列等情況下,終止條件似乎是任意的,設定上限確保了程式碼的可預測性和穩定性。

原則三:不要用 Heap 記憶體(Don’t use the Heap)

NASA 建議僅使用 Stack 記憶體,而不使用 Heap 記憶體,因為記憶體錯誤和問題通常源於 Heap 的使用和垃圾回收(Garbage Collection)機制。靜態程式碼分析無法對這些系統進行驗證。通過完全避免使用 Heap 記憶體,並對 Stack 記憶體的使用量設定上限,可以精確預測程式碼所需的記憶體量,消除使用後的錯誤和記憶體洩漏。

原則四:限制函式大小(Limit Function Size)

每個函式應該只執行一個任務,儘管可能需要多個步驟。確保函式的長度不超過 60 行(約一頁大小),有助於他人審查並理解函式的功能。同時,函式越小且內容精簡,就越容易作為單獨的單元進行測試。若一個函式長達 400 行並且有多層巢狀結構,往往意味著程式碼結構混亂,思路不清晰。

原則五:最低作用域聲明變量(Practice Data Hiding)

在可能的最低作用域(scope)宣告變數,可以減少訪問這些變數的程式碼數量,同時減少除錯時對錯誤值的追蹤範圍。這樣的寫法不僅能減少程式碼中訪問這些變數的地方,也能減少可能發生錯誤的地方。

原則六:處理回傳值(Check Return Values)

對於非 void 函式,檢查所有的回傳值至關重要。忽略回傳值可能導致意外行為。NASA 建議將被忽略的回傳值顯式轉換為 void 型別,以表明有意省略,並有助於程式碼審查。

原則七:有限使用 C 前置處理器(Limit the Preprocessor)

要謹慎使用 C 前置處理器(C preprocessor),尤其是在條件編譯方面。過度使用前置處理指令可能導致程式碼混亂,並顯著增加測試工作量。將前置處理器的使用限制在包含檔案和簡單條件中,有助於提高程式碼的清晰度和可維護性。

原則八:限制指標的使用(Restrict Pointers Use)

指標(pointer)是一種功能強大但容易不當使用的工具。NASA 建議將指標的反參照(dereference)限制為一層。透過這種限制,能夠更好地追蹤指標並建立適當的結構。同時,NASA 建議限制函式指標的使用,因為函式指標會使程式碼的控制流程圖變得難以理解,且難以進行靜態分析和完整測試。

原則九:啟用編譯警告和嚴格模式(Be Pedantic)

編譯程式碼時應啟用所有的警告,並以嚴格模式編譯。這樣做可以確保編譯器對程式碼中可能出現的問題進行提醒並視為錯誤。將警告視為錯誤將確保不會忽視掉有問題的程式碼,提高代碼的正確性和遵循最佳實踐。

原則十:靜態程式碼分析和單元測試(test test test)

NASA 強調使用多個靜態代碼分析器進行代碼分析,並使用不同的規則集。這種全面的分析方法有助於在部署之前識別和糾正潛在問題。此外,全面的單元測試驗證代碼的行為,提高可靠性和穩健性。


結論

在將你的新安全程式碼的火箭送入太空之前,觀看這段影片,你將學到有關程式設計的新知識。這些 NASA 的「十個原則」經驗教訓可以幫助我們編寫更安全、可靠的程式碼,並減少崩潰和錯誤的風險。


《DTW 數位科技週報》

如果想要每週獲得最新的數位科技、區塊鏈及人工智慧新聞整理,歡迎訂閱免費電子報:《DTW 數位科技週報》