How to use Clang Static Analyzer,
IntroductionClang
宏觀上講,Clang是一個項目名稱。微觀上,類似於GCC,Clang是一個C語言、C++、Objective C語言的輕量級編譯器,它是Clang項目的一部分。
相比較於GCC,Clang的編譯速度更快,佔用的記憶體更少。Clang的錯誤提示與警告資訊也比GCC更加準確清晰。此外,Clang基於庫的模組化設計,易於IDE的整合並且遵循LLVM BSD協議。
Clang Static Analyzer
Clang Static Analyzer是一個能尋找C語言、C++、Objective-C(C語言家族)漏洞的源碼分析工具。
目前,Clang Static Analyzer可以作為一個獨立的工具,也可以在Xcode開發環境(Mac os)中運行。Clang Static Analyzer作為一個獨立的工具可以從命令列(如ubuntu的終端)中啟動,並且它運行在構建一個程式碼程式庫過程中。
Clang Static Analyzer作為Clang項目的一部分,是一個百分之百開源的軟體。就像Clang編譯器一樣,Clang Static Analyzer可以像一個C++庫一樣整合到其他應用程式中。
scan-build & scan-view
scan-build是一個命令列工具,它能夠協助使用者運行靜態分析器(static analyzer)檢查原始碼,使其能正常的構建。靜態分析器與代碼的編譯是互不影響並且同步執行的,即:當一個項目在構建中,源碼會被靜態分析器分析並尋找源碼的漏洞。如:
$ scan-build make
當構建完成時,結果將會以一個web網頁的形式呈現給使用者。類似於scan-build,scan-view也是一個命令列工具。它能開啟由scan-build產生的web網頁,顯示bug報告。
How to install
不同平台Clang的安裝方法有所不同:Mac OS X環境下安裝方法:MAC OS CLANG,本文介紹Ubuntu系統下的安裝方法,除Mac OS X的其他平台都與ubuntu類似。
apt-get 安裝
用apt-get直接安裝,只需要在終端中輸入:
$ sudo apt-get install clang
這種方法適用於對版本要求不高的使用者,優點是簡單快速。
源碼安裝
如果對Clang版本要求很高,就需要手動對Clang原始碼編譯安裝,這也是官網建議的安裝方法。這種方法優點是能得到最新版本,缺點是耗時麻煩。
- 編譯Clang
- 調整scan-build和scan-view目錄
官網給的源碼make install並不會安裝scan-build和scan-view工具。編譯完成後,編譯出的scan-build和scan-view分別在$(SRCDIR)/tools/clang/tools/scan-build和$(SRCDIR)/tools/clang/tools/scan-view中($(SRCDIR)是下載的llvm路徑)。為防止誤刪除這兩個目錄,通常情況下,會把這兩個目錄放到根目錄下(比如放到/usr/share/clang下),如果目前的目錄在llvm目錄下。$ sudo mkdir /usr/share/clang/scan-build -p$ sudo cp ./tools/clang/tools/scan-build/* /usr/share/clang/scan-build/$ sudo mkdir /usr/share/clang/scan-view -p$ sudo cp -r ./tools/clang/tools/scan-view/* /usr/share/clang/scan-view/$ cd /usr/bin$ sudo ln -s ../share/clang/scan-build/scan-build$ sudo ln -s ../share/clang/scan-view/scan-view
至此,scan-build和scan-view工具就可以使用了,但是由於源碼指令碼並沒有指定clang的路徑,所以每次使用scan-build工具時必須寫出clang的路徑。這樣非常麻煩,解決這個問題,可以修改scan-build指令碼。sudo vi /usr/bin/scan-build# Find 'clang'if (!defined $AnalyzerDiscoveryMethod) {- - $Clang = Cwd::realpath("$RealBin/bin/clang");+ $Clang = Cwd::realpath("/usr/bin/clang"); if (!defined $Clang || ! -x $Clang) { $Clang = Cwd::realpath("$RealBin/clang"); }
即:將第一個$RealBin改為/usr。這樣就向scan-build指定了Clang的位置。Clang Static Analyzer就完整安裝完成了。
Standard Operation ProcedureClang編譯器
與GCC相類似,Clang也整合先行編譯器、彙編器和連結器於一體,使用的文法格式也為:
clang [options] <inputs>
其大多數編譯選項也與GCC類似,如-E只執行先行編譯、-S產生組合語言檔案(以.s結尾)、-c選項只編譯不連結等。詳細的選項說明可以man clang或者clang -help查看。Clang編譯器的使用者手冊詳見:CLANG COMPILER USER‘S MANUAL
與GCC不同的一點是使用--analyze選項可以啟動靜態分析器,如
$ clang --analyze test.c
在在運行這條指令時,Clang Static Analyzer會被啟動,分析test.c中的bug。
scan-build和scan-view
checkers
Clang Static Analyzer就是利用不同的checker來檢測源碼不同類型的bug的。靜態分析器會預設使用6類checkers(default checker):
- Core Checkers:提供一些一般性的檢查,比如是否被0除、是否使用null 指標和使用未初始化參數等。
- C++ Checkers:提供C++檢查。
- Dead Code Checkers:檢查沒有使用的代碼。
- OS X Checkers:檢查Objective-C和Apple's SDKs的使用方式。
- Security Checkers:檢查不安全API的使用和基於CERT Secure Coding Standards的檢查。
- Unix Checkers:檢查Unix和POSIX API的使用方式。
其中,每一類的checkers中包含有不同的checker負責檢查不同細分類型的bug。比如core checkers類中的一個checker: core.CallAndMessage 該checker主要負責檢查函數調用的邏輯錯誤或者資訊表達的錯誤,比如未初始化的參數,空的函數指標等。例如:
// Cstruct S { int x;};void f(struct S s);void test() { struct S s; f(s); // warn: passed-by-value arg contain uninitialized data}
可以使用選項--help-checkers來查看預設checkers列表。-enable-checker和-disable-checker用來使用和禁用checker,例如
$ scan-build --help-checkers$ scan-build -enable-checker core.CallAndMessage gcc test.c$ scan-build -disable-checker core.CallAndMessage gcc test.c
如果不禁止使用某個checker,scan-build會自動使用預設的checkers。詳細的checkers功能介紹請看後面的章節“The functions of default checkers”或AVAILABLE CHECKERS
The flow chart of scan-build & ccc-analyzer
用來啟動靜態分析器的scan-build是一個perl指令碼。ccc-analyzer與scan-build一樣,也是一個perl指令碼。ccc-analyzer指令碼是一個中間檔案,使用者不直接接觸,但是會被scan-build調用。
scan-build flow chart
以上為scan-build指令碼執行的前半部分,用來處理scan-build option。
第二部分的scan-build主要處理command和command option。
scan-build總結:
ccc-analyzer flow chart
ccc-analyzer指令碼流程總結:
How to use scan-build to find bugs分析一個使用未初始化的函數指標的程式碼分析MIPS架構linux分位中的private appsThe functions of default checkers
Clang Static Analyzer中default checkers共有6類,分別為:Core Checkers, C++ Checkers, Dead Code Checkers, OS X Checkers, Security Checkers和Unix Checkers。以下為除OS X Checkers的其他5類中各個checker的功能描述。
註: