作者:IAR 編程語(yǔ)言的現代化和更好的編碼技術(shù)與從機械計算機到現代軟件開(kāi)發(fā)流程的演變直接相關(guān)。我們已經(jīng)從高度專(zhuān)業(yè)化、主要是數學(xué)符號的表示法過(guò)渡到了更接近人類(lèi)語(yǔ)法的高級編程語(yǔ)言,這一進(jìn)步歸功于編譯器技術(shù)。然而,這也打開(kāi)了代碼缺陷之門(mén)。 C和C++ 等高級編程語(yǔ)言,包含大量未定義的行為,而不同的編譯器對這些行為的解釋可能略有不同,這可能會(huì )導致未知或不希望出現的副作用,最終轉化為缺陷。 查找和修復這些缺陷可能會(huì )占用高達80%的開(kāi)發(fā)時(shí)間,具體取決于開(kāi)發(fā)機構的成熟程度。這引出了一個(gè)明顯的結論:代碼質(zhì)量是一個(gè)大問(wèn)題。那么,為什么不盡量避免缺陷,以減少調試所需的時(shí)間呢? 順便說(shuō)一句,我們現在仍然在軟件中使用“錯誤”和“調試”這些概念,但這些詞的起源可以追溯到哈佛大學(xué)的機械計算機。當時(shí),一只飛蛾卡在繼電器中,這一事件被記錄為計算機歷史上第一個(gè)“錯誤”或缺陷。 一次又一次重復同樣的錯誤 眾所周知,在Web、應用程序、桌面,甚至嵌入式開(kāi)發(fā)中,開(kāi)發(fā)人員往往會(huì )無(wú)意間一次又一次地在他們的源代碼中引入相同類(lèi)型的錯誤。這個(gè)結論來(lái)自于多個(gè)重要機構,如NASA、貝爾實(shí)驗室和MITRE,他們進(jìn)行了多項調查和研究。常見(jiàn)缺陷的例子包括在C++代碼(甚至C代碼)中沒(méi)有進(jìn)行分配后的釋放,以及使用沒(méi)有原型的函數,因此無(wú)法在編譯時(shí)進(jìn)行嚴格的類(lèi)型檢查。這項研究的結果列出了最佳編程實(shí)踐或推薦的編程實(shí)踐,它們可以識別有風(fēng)險的和不良的編碼行為。 有許多關(guān)于如何提高代碼質(zhì)量的指南和編碼實(shí)踐,它們都基于常見(jiàn)的錯誤,并指出了如何在將來(lái)避免這些常見(jiàn)錯誤。其中一些技巧和實(shí)踐已經(jīng)成為被廣泛接受的標準(比如MISRA-C和CERT-C),特別是在汽車(chē)、醫療和鐵路等關(guān)鍵行業(yè)中,以確保應用程序的代碼安全性(code safety)和代碼防護能力(code security)。諸如IEC 61508、EN 50128和ISO 26262等功能安全標準建議[或強烈建議,具體取決于安全完整性等級(SIL)或汽車(chē)安全完整性等級(ASIL)]使用靜態(tài)和運行時(shí)分析工具,以滿(mǎn)足標準。因為安全關(guān)鍵系統中的缺陷可能會(huì )導致嚴重后果,如人員傷亡或環(huán)境破壞。 關(guān)注可靠性 安全編碼技術(shù)要綜合考慮代碼質(zhì)量、代碼安全性和代碼防護能力。代碼安全性關(guān)注的是軟件的可靠性,而代碼防護能力則旨在防止不必要的活動(dòng),并且在遭受攻擊時(shí)確保系統安全。這兩者都高度依賴(lài)于代碼質(zhì)量,因為代碼質(zhì)量是每個(gè)可靠應用程序的基礎。 安全編碼技術(shù)和標準的目標是推動(dòng)軟件的安全性,以確保所需的可靠性。然而,同樣重要的是提高源代碼的可讀性和可維護性。更高效、更易讀的代碼意味著(zhù)源代碼更加健壯、缺陷更少且在未來(lái)可用,有助于提高代碼的可重用性。 MISRA C是最成熟的軟件開(kāi)發(fā)標準之一,可以避免常見(jiàn)的缺陷和漏洞。當然,還有一些其他指南,如CWE和CERT-C編碼標準,這些標準對于任何嵌入式應用程序都是強烈推薦的。下面讓我們更深入地了解這些編碼標準。 MISRA C標準 MISRA C由汽車(chē)行業(yè)軟件可靠性協(xié)會(huì )(Motor Industry Software Reliability Association)開(kāi)發(fā),它的目標是提高嵌入式系統中代碼的安全性、可移植性和可靠性,尤其是那些使用ISO C編程的系統。 MISRA C標準的第一版名為《車(chē)載軟件C語(yǔ)言開(kāi)發(fā)指南》,于1998年發(fā)布,正式名稱(chēng)為MISRA-C:1998。之后于2004年和2012年進(jìn)行了更新,添加了更多的規則。另外,還有基于C++ 2003的MISRA C++ 2008標準。此后,MISRA C: 2012的修正案1又添加了14條附加規則,重點(diǎn)關(guān)注ISO C安全指南(Secure Guidelines)中強調的安全問(wèn)題(security concerns)。其中一些規則解決了在許多嵌入式應用程序中已知的安全漏洞之一:與使用不可信數據相關(guān)的特定問(wèn)題。 MISRA規則可以幫助您在提交代碼進(jìn)行正式構建之前發(fā)現問(wèn)題,因此通過(guò)這種方式發(fā)現的缺陷就好像缺陷從未存在過(guò)一樣。MISRA規則的設計是以安全性和可靠性為前提的,同時(shí)也讓代碼更容易移植到其他工具和架構上。 CWE and CERT C/C++ CWE,即通用缺陷列表(Common Weakness Enumeration),是一個(gè)由社區開(kāi)發(fā)的有關(guān)軟件缺陷的詞典。CWE提供了一套統一的、可衡量的軟件缺陷,以便更好地理解和管理它們,并且可以支持能夠發(fā)現它們的高效軟件安全工具和服務(wù)。 CERT C/C++安全編碼標準(Secure Coding Standards)是由計算機緊急響應小組(Computer Emergency Response Team,CERT)發(fā)布的標準,提供了有關(guān)C/C++編程語(yǔ)言中安全編碼(secure coding)的規則和建議。 實(shí)施安全編碼技術(shù) 作為通常性的建議,每個(gè)嵌入式應用程序至少都應遵循MISRA(對于安全關(guān)鍵系統,MISRA 是強制性的)、CWE和CERT C/C++標準。 遵循這些編碼標準之后,在運行時(shí),您的應用程序仍然可能會(huì )受到算術(shù)問(wèn)題、緩沖區溢出、邊界問(wèn)題、堆完整性和內存泄漏等問(wèn)題的影響。要檢測到這些錯誤,可以在可能發(fā)生潛在錯誤的所有位置插入特定的檢測代碼或斷言。然而,手動(dòng)添加指令來(lái)檢查并在運行時(shí)報告問(wèn)題是一項非常耗時(shí)的任務(wù)。 要遵守所有這些指南和標準,您需要遵循近700條規則和要求,同時(shí)還需要在源代碼中添加檢測代碼。那么,如何實(shí)施安全編碼技術(shù)并遵循所有這些規則呢? 使用自動(dòng)化工具 提高軟件質(zhì)量、安全性和可靠性的最佳方法是使用自動(dòng)化工具。這可以通過(guò)使用高質(zhì)量的編譯器和鏈接器(最好是經(jīng)過(guò)功能安全認證的編譯器和鏈接器),以及自動(dòng)化的靜態(tài)分析和運行時(shí)分析工具來(lái)實(shí)現。 IAR作為全球領(lǐng)先的嵌入式系統開(kāi)發(fā)軟件解決方案供應商,所提供的集成開(kāi)發(fā)環(huán)境IAR Embedded Workbench就包括了編譯器、匯編器、鏈接器和調試器,并無(wú)縫集成了靜態(tài)分析工具 C-STAT和運行時(shí)分析工具C-RUN,形成了完整的工具鏈。憑借這些強大的功能,IAR Embedded Workbench可以確保代碼的穩健性、安全性和高質(zhì)量。 我們先來(lái)看看編譯器和鏈接器,它們應該支持現代編程語(yǔ)言,比如最新的C(ISO/IEC 9899:2018)和C++(ISO/IEC 14882:2020,也稱(chēng)為C++20修訂版),這樣它們就會(huì )在出現可疑情況或語(yǔ)法問(wèn)題時(shí)生成警告,例如,易失性?xún)却嬖L(fǎng)問(wèn),其求值順序可能會(huì )影響應用程序的邏輯。 編譯器和鏈接器警告(warnings)是您的第一步靜態(tài)分析檢查,絕不能忽視,特別是在功能安全環(huán)境中。最佳建議是通過(guò)更改編譯器設置將所有警告視為錯誤,這樣就可以將這些警告轉換為錯誤。這將讓開(kāi)發(fā)人員修復代碼中的所有不明確之處,因為所有問(wèn)題都將被視為真正的問(wèn)題。 靜態(tài)分析工具可以幫助您發(fā)現代碼中最常見(jiàn)的缺陷,同時(shí)還可以幫助您找出開(kāi)發(fā)人員在嘗試編寫(xiě)代碼時(shí)通常不會(huì )考慮或擔心的問(wèn)題,尤其是當他們只是編寫(xiě)腳手架代碼以使某些功能正常運行時(shí)。這種類(lèi)型的工具確實(shí)可以幫助您開(kāi)發(fā)更高質(zhì)量的代碼,因為它們可以幫助您實(shí)施編碼標準。IAR的C-STAT靜態(tài)分析工具無(wú)需任何安裝和靜態(tài)代碼分析工程創(chuàng )建,只需要進(jìn)行簡(jiǎn)單的規則設置,就可以在構建(Build)成功之后進(jìn)行靜態(tài)代碼分析,非常適合開(kāi)發(fā)人員在日常開(kāi)發(fā)過(guò)程中使用。 此外,還有動(dòng)態(tài)或運行時(shí)分析工具,可以捕獲僅在運行時(shí)出現的代碼缺陷。動(dòng)態(tài)或運行時(shí)分析工具可以在于軟件調試器中執行程序時(shí)發(fā)現代碼中的實(shí)際和潛在錯誤。IAR的C-RUN動(dòng)態(tài)分析工具通過(guò)簡(jiǎn)單的配置、重新編譯、運行,即可實(shí)現算術(shù)檢查、邊界檢查和堆檢查。使用C-RUN無(wú)需對現有流程做任何修改,可作為日常開(kāi)發(fā)工作流程的自然組成部分,這極大地降低了動(dòng)態(tài)分析工具的使用門(mén)檻。 當您查看系統中可能存在的所有缺陷時(shí),靜態(tài)分析工具擅長(cháng)找到某些類(lèi)型的缺陷,而運行時(shí)分析工具則擅長(cháng)找到其他類(lèi)型的缺陷。有時(shí)它們可能會(huì )有重疊,但有時(shí)只有一種工具才能檢測到某個(gè)缺陷。要獲得最全面的代碼分析,最好將這兩種工具結合使用,并將它們與頂尖的構建工具集成在一起。下圖的矩陣很好地展示了在結合不同工具進(jìn)行檢測時(shí)完整的缺陷覆蓋范圍。 ![]() 總結 隨著(zhù)嵌入式系統的復雜性提高,對于嵌入式軟件的要求也越來(lái)越高,其中最核心最根本的是代碼質(zhì)量,而遵循編碼標準的安全編碼技術(shù)是提高代碼質(zhì)量的最佳實(shí)踐。實(shí)施安全編碼技術(shù)最有效的方式是應用自動(dòng)化工具,包括編譯器、鏈接器、靜態(tài)分析工具、運行時(shí)分析工具。這樣可以高效地在開(kāi)發(fā)過(guò)程中提高代碼質(zhì)量及其安全性和可靠性,既減少了項目的開(kāi)發(fā)時(shí)間和成本,又提高了產(chǎn)品的質(zhì)量和競爭力。 |