生成LLVM文件之后,做下面兩件事,我們差不多就終於可以開始我們正式的編寫checker之旅了。
1. clang,can-build,scan-view,ccc-analyzer全部添加正確的系統路徑
2. 安裝windows下的Perl64解釋器並添加系統路徑
到這里差不多就可使用了,我們來測試一下:
clang --help
clang -cc1 -analyzer-checker-help (列出所有可用的checker)
下面我們給出一段測試程序
char * test_fixed_address_checker() { char *p; p = 0x1000; return p; }
將它保存為test.c,並放在桌面上,方便我們測試(強迫症者除外),然后我們打開cmd,復制粘貼下面三行:
cd desktop
type test.c
clang --analyze -Xclang -analyzer-checker=alpha.core.FixedAddr test.c
結果為:
下面我們來試下scan-build
scan-build --use-analyzer=D:\LLVM\build\Debug\bin\clang.exe clang -cc1 test.c
--use-analyzer=D:\LLVM\build\Debug\bin\clang.exe 中--use-analyzer 就是要告訴系統一個可用的clang的位置,也就是我們配置的clang 的環境變量path的值。
實踐測試了代碼之后,我們來DIY吧!下面來寫自己的checkers。我就按照自己放置的路徑分享了,大家可以對照自己的做調整:
1. 打開D:\LLVM\llvm\tools\clang\lib\StaticAnalyzer\Checkers
2. 添加自定義的.cpp 的checker文件,比如:MyDefinedChecker.cpp
並在該文件中添加注冊函數:
void ento::registerMyDefinedChecker(CheckerManager &mgr) { mgr.registerChecker<MyDefinedChecker>(); }
千萬別像我一樣傻,除了上面的代碼什么都不往里面放,就想要皆大歡喜,實際是要放下下面這一段試試的,因為第一步你要在VS中沒有便宜錯誤,之后還不能有鏈接錯誤,所以雖然沒有實際內容,請放下面的內容:
#include "ClangSACheckers.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" using namespace clang; using namespace ento; namespace { class MyDefinedChecker : public Checker< check::PreStmt<BinaryOperator> > { mutable std::unique_ptr<BuiltinBug> BT; public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; }; } void MyDefinedChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const { } void ento::registerMyDefinedChecker(CheckerManager &mgr) { mgr.registerChecker<MyDefinedChecker>(); }
3. 在D:\LLVM\llvm\tools\clang\include\clang\StaticAnalyzer\Checkers中找到Checkers.td文件,在Checkers.td文件中為自己的checker添加分組信息,也就是說你要讓自己的checker繼承自哪一類,差不多在159行左右,大家把自己的checker放在下圖的這個package里面:CoreAlpha
代碼為:
def MyDefinedChecker : Checker<"MyDefined">,
HelpText<"Check for a self-defined error">, DescFile<"MyDefinedChecker.cpp">;
4. 最后在D:\LLVM\llvm\tools\clang\lib\StaticAnalyzer\Checkers的CMakeLists.txt中添加類名.cpp,比如:MyDefinedChecker.cpp放在59行,因為貌似是按照字母順序表來的。
現在打開LLVM.sln, 在解決方案中搜索剛寫的checker名,找到自己的源文件,檢查是否有錯誤,如果沒有,注意點擊該源文件所屬的項目,只生成這個項目即可,否則會很費時間,特別慢,特別卡,要崩潰的感覺。
現在來測試一下:
還不錯的感覺哦,哈哈!
如果效果不是上圖所示,可以右擊clang這個項目,點擊生成,就會把變化的內容重新編譯,如果存在連接問題,如果是LINK2019,可能是只寫了函數聲明,沒有定義。
今天就啰嗦這么多吧,下一節,我們會簡單介紹如何真正開始寫一些自己經過設計的checker。
補充說明:
1.如果是打開LLVM.sln,然后點開clang libraries里面的clangStaticAnalyzerCheckers,然后右擊Source Files直接添加的,其他文件也是在項目里打開直接修改的,就直接生成clang項目就可以,不需要像2中再Cmake生成一次。
2.如果是根據目錄從文件夾打開添加了各個對應文件,就要用Cmake重新生成一下這個VS項目: cmake -G "Visual Studio 14" .. 然后,打開LLVM.sln,生成clang這個項目。
參考文章:
http://blog.csdn.net/tuqinag/article/details/46940633
https://sec.xiaomi.com/article/21