代碼靜態(tài)分析
代碼靜態(tài)分析是指在不運行代碼的情況下根據(jù)代碼的靜態(tài)信息,對代碼的各個維度進行分析滴须。
代碼靜態(tài)分析一般包括如下三個方面:
- 編碼規(guī)范檢查:保證代碼的風格和團隊的要求一致舌狗,對于多人合作的軟件項目,這是代碼易于理解和維護的基本要求扔水。
- 代碼靜態(tài)度量:一般指代碼復雜度度量痛侍,包括分支復雜度、圈復雜度魔市、代碼深度等主届。除此之外還包括代碼重復率等指標。
- 代碼缺陷檢查:指通過靜態(tài)分析發(fā)掘代碼潛在的故障和缺陷待德。例如空指針異常君丁、內(nèi)存越界、堆棧溢出等潛在的軟件bug将宪。由于只是基于靜態(tài)代碼分析绘闷,所以故障缺陷只是意味存在著一個潛在的故障可能橡庞,仍需要人工事后分析。
代碼靜態(tài)分析可以通過人工分析和工具分析兩種途徑簸喂。人工分析也就是我們熟知的代碼走查毙死,被認為是一項提高軟件質(zhì)量非常有效的實踐活動。然而對于擁有巨大代碼庫的軟件喻鳄,人工檢查成本大扼倘,而且枯燥重復,這時借助工具可以大大提高代碼靜態(tài)檢查的效率除呵。讓工具覆蓋常見低級缺陷再菊,進行大規(guī)模掃描,而讓人去關(guān)注邏輯性強的分析檢查颜曾,可以有效發(fā)揮工具和人的長處纠拔。另外工具也讓自動化變?yōu)榭赡埽梢杂行岣吖こ绦省?/p>
代碼靜態(tài)分析的價值
對于軟件泛豪,故障發(fā)現(xiàn)的時間越晚修復的成本會成指數(shù)上升趨勢稠诲。有效的代碼靜態(tài)分析能夠在軟件運行之前暴露潛在的軟件問題,對于大的軟件項目可以節(jié)省巨大的成本臀叙。通過代碼靜態(tài)檢查价卤,可以獲得如下收益:
- 可以提早發(fā)現(xiàn)代碼的風格問題,第一時間對代碼風格進行統(tǒng)一慎璧;
- 可以盡早的得到代碼的度量數(shù)據(jù)胸私,對代碼的復雜度提供可靠數(shù)據(jù),以指導重構(gòu)工作的開展嘱蛋;
- 發(fā)現(xiàn)潛在的代碼故障五续,避免故障泄露到后續(xù)的運行期疙驾,節(jié)省故障的定位成本和解決成本它碎;
最后,將代碼靜態(tài)分析工具部署在持續(xù)集成服務器上傻挂,可以實時獲得上述反饋挖息。通過持續(xù)集成的實時監(jiān)控和反饋套腹,可以持續(xù)地防范代碼的腐化和缺陷。
代碼靜態(tài)分析的途徑
代碼走查
一說起代碼靜態(tài)分析幢码,人們往往先想到的是靜態(tài)檢查工具尖飞。事實上根據(jù)業(yè)界的統(tǒng)計政基,最有效的代碼靜態(tài)分析反而是人工代碼走查。但是傳統(tǒng)的人工走查由于缺少工具和流程的支撐咕娄,容易流為形式珊擂,因此Google和Facebook等企業(yè)都研發(fā)了簡單易用的代碼走查工具摧扇,并將代碼走查活動部署在代碼提交的關(guān)鍵路徑上,使其成為代碼提交流程的一部分吁峻。借助工具讓代碼走查變得不再麻煩在张,并通過將這一實踐固化在代碼提交流程中而避免了實踐遺漏帮匾。
例如當前流行的Code Review工具:Facebook開源的Phabricator。Phabricator需要一臺服務器進行部署缸夹,并配置和代碼倉庫(例如SVN)進行連接。開發(fā)人員代碼提交會自動觸發(fā)Phabricator發(fā)起一次代碼評審活動橡类,只有根據(jù)評審意見修改了代碼被認定評審通過芽唇,代碼才會被準許提交進SVN中。這一切都由Phabricator進行流程控制亲雪。另外Phabricator提供了一個交互式網(wǎng)頁服務疚膊,在上面可以針對代碼逐行評審并提交評審意見寓盗,被評審者可以對評審意見作出回復』裕可見Phabricator還提供了一個評審意見交流平臺善炫。
另外一個類似的工具是Gerrit,主要針對git倉庫窜醉。
工具檢查
通過工具對代碼進行靜態(tài)分析檢查是一種更加高效的手段榨惰。靜態(tài)分析工具一般分為靜態(tài)度量工具和靜態(tài)檢查工具静汤。
代碼靜態(tài)度量工具
靜態(tài)度量工具主要是對代碼進行靜態(tài)復雜度度量√俾眨基本的包括代碼行數(shù)杰捂,函數(shù)數(shù)等棋蚌,再下來就是分支復雜度,圈復雜度蒿往,代碼深度等等瓤漏,通過這些數(shù)據(jù)颊埃,可以展現(xiàn)當前的代碼規(guī)模以及復雜度情況。復雜度結(jié)果為代碼提供了可視化數(shù)據(jù)饥漫,可以對代碼的重構(gòu)提供指導罗标,還可以借助復雜度度量結(jié)果對代碼的重構(gòu)效果進行度量闯割。另外將復雜度檢查工具集成進持續(xù)集成服務器的話,可以設(shè)置規(guī)則避免過高復雜度的代碼入庫宾尚。新提交的代碼只有在滿足復雜度要求的情況下才允許合入代碼庫谢澈,這可以在第一時間防止代碼腐化澳化。目前大多數(shù)語言都可以找到開源易用的復雜度度量工具,這些工具有些可以直接集成進開發(fā)IDE工具中井濒,讓開發(fā)人員在寫代碼的時候就能獲得度量結(jié)果列林。
代碼靜態(tài)檢查工具
靜態(tài)檢查工具主要是通過掃描發(fā)掘代碼中隱藏的潛在故障希痴。一般通過以下維度衡量一個代碼靜態(tài)檢查工具:
- 檢查規(guī)則數(shù):支持的檢查規(guī)則越多則能發(fā)現(xiàn)越多的潛在故障;
- 誤報率:指在報告的潛在故障中虏缸,非真實故障所在的比率。誤報率越低越好窥岩;
- 易用性:有的工具支持本地部署檢查宰缤,有的則需要把所有的檢查數(shù)據(jù)上傳服務器。不同工具的易用性差別挺大朦乏;
- 收費模式:免費還是收費呻疹,收費的話收費模式如何语淘;
遺憾的是對于C/C++,當前市面上功能強大的代碼靜態(tài)檢查工具皆是商用的姑蓝。開源的工具在規(guī)則數(shù)以及對潛在故障的挖掘深度上和商用工具的差距還是挺明顯的吕粗。一般由于商用工具比較昂貴颅筋,所以大多企業(yè)會選擇將開源和收費工具結(jié)合使用,只在關(guān)鍵項目階段部署使用商用工具议泵,而開發(fā)人員日常掃描則使用開源工具。當然具體策略需要和產(chǎn)品類型項目情況等相結(jié)合型奥。
代碼靜態(tài)分析工具對比
對于C++語言厢汹,代碼度量工具大多選擇SourceMonitor谐宙,這款軟件是免費的,功能包括基本的代碼行搭综、函數(shù)數(shù)量、類數(shù)量統(tǒng)計舰讹,還包括分支比例度量、圈復雜度度量、代碼深度度量等奋姿,并且會根據(jù)度量結(jié)果生成報表素标。
C++的代碼靜態(tài)檢查工具,常用的有cppcheck寓免、pclint计维、coverity等,這些軟件除了可以檢查代碼規(guī)范蜈首,還可以掃描分析代碼的潛在故障欢策。我們按照以下維度進行對比:
對比項 | cppcheck | pclint | coverity | klocwork |
---|---|---|---|---|
收費模式 | 免費 | PC license $389 | 多模式收費赏淌;和代碼規(guī)模和license類型有關(guān)。網(wǎng)站沒有明確報價俺孙,具體報價需要咨詢客服 | 收費缩擂;網(wǎng)站沒有明確報價胯盯,需要根據(jù)軟件規(guī)模和license類型具體咨詢客服 |
支持語言 | C/C++ | C/C++ | C/C++/Java/C# | C/C++/Java/C# |
支持平臺 | 跨平臺 | 跨平臺 | 跨平臺 | 跨平臺 |
支持Jenkins集成 | 支持 | 支持 | 支持 | 通過第三方插件 |
掃描結(jié)果 | 本地報表 | 本地結(jié)果 | 需上傳服務器 | 需上傳服務器 |
規(guī)則數(shù) | 200+ | 900+ | 500+ | 沒有官方數(shù)字 |
誤報率 | 中等 | 高 | 低 | 低 |
易用性 | 易用 | 易用 | 復雜 | 復雜 |
從前面的分析可見,雖然開源的工具易用性高憎乙、容易和持續(xù)集成服務器進行集成,但缺點是掃描效果無論是在深度和廣度上都不如商業(yè)工具该押。另外規(guī)則數(shù)越多誤報率就越高蚕礼,所以這是一個需要平衡的點。
代碼靜態(tài)分析工具部署
對于代碼靜態(tài)度量工具奠蹬,由于是開源免費的囤躁,一般開發(fā)人員和持續(xù)集成服務器上都進行部署。開發(fā)人員代碼提交前先自檢狸演,自檢復雜度在要求范圍內(nèi)再提交入庫僻他。而持續(xù)集成服務器通過統(tǒng)一構(gòu)建再進行確認中姜。
而對于代碼靜態(tài)檢查工具,從前面的分析可見丢胚,雖然開源的工具易用性高、容易和持續(xù)集成服務器進行集成兔跌,但缺點是掃描效果無論是在深度和廣度上都不如商業(yè)工具峡蟋。但這并不能說開源工具就沒有了價值。一般項目的做法是在軟件流水線的不同階段部署不同的工具仅乓,來達到整體成本收益比最好夸楣。
一種常見的部署方式是,在每個開發(fā)人員的機器上部署cppcheck開源工具,這樣每個開發(fā)人員都可以在本地實時對代碼進行檢查羞延,將初級的錯誤直接消滅在本地。而持續(xù)集成上則部署商業(yè)靜態(tài)檢查工具孵班,這樣可以降低商業(yè)工具部署的機器數(shù),還能降低商業(yè)工具的掃描次數(shù)花椭,從而節(jié)省費用開支。一般在持續(xù)集成上可以設(shè)置每日或者每個發(fā)布版本用商業(yè)工具進行一次掃描丹允,具體配置規(guī)則和項目特點有關(guān)。
集成了代碼走查工具折柠,代碼度量工具和代碼檢查工具的持續(xù)集成服務器如下圖扇售。
其它注意事項
- 在代碼靜態(tài)檢查之前承冰,最好先將編譯告警也消除掉食零。從檢查基礎(chǔ)的修復開始做起。
- 對檢查工具報的錯誤要第一時間修復娜搂,不要累計百宇。大規(guī)模修改引入的風險往往不可控秘豹。
- 由于工具會有誤報,所以使用工具仍避免不了人工分析婚苹,人工分析的質(zhì)量仍需要保證鸵膏。
- 不要因為有了工具而忽略了人工代碼走查的重要性谭企。
- 由于靜態(tài)分析只是依據(jù)代碼的靜態(tài)視圖做分析,不能替代代碼的運行態(tài)測試非区,例如單元測試盹廷。
相關(guān)推薦材料
- 針對每種語言的靜態(tài)檢查工具列表:https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis