使用clangtidy進(jìn)行自定義checkers實(shí)現(xiàn)告警提醒和自動(dòng)fix功能
Clang-Tidy和Clang Static Analyzer
- Clang-Tidy的底層邏輯主要是通過文本和抽象語法樹匹配享钞,通過AST Matchers來替換、增加或刪除模式妨猩。
-?Clang Static Analyzerd的底層邏輯也是利用語法樹,可以更進(jìn)一步通過符號(hào)執(zhí)行赖晶,通過模擬程序執(zhí)行流程發(fā)現(xiàn)bug
- Clang-Tidy介紹(屬于Clang)
基于Clang的C++Linting工具框架
? 完全訪問AST和預(yù)處理器
??Clang-Tidy是可擴(kuò)展的–可以進(jìn)行自定義check
? 現(xiàn)有200多個(gè)check
? 可讀性中贝、效率、正確性评抚、現(xiàn)代化
? 高度可配置
? 可以在許多地方自動(dòng)修復(fù)代碼
示例說明:
#define ZERO 0
int function(int b)
int a c;
switch(b){
case 1: a=b/0; break; // AST可以識(shí)別
case 2: a= b/ZERO;break; // AST可以識(shí)別
case 4: c=b-4;a=b/c;break;// AST可以無法識(shí)別镀首,需要Symbolic Execution
};
return a;
clang-tidy check的使用
Dump AST : clang –cc1 –ast-dump init.cpp
? clang-tidy? -list-checks? ? ? ? ? ? //查看clang-dity生效的checks
? clang-tidy -list-checks -checks=*?? //查看clang-dity可用的checks
? clang-tidy --checks=-*,cppcoreguidelines-init-variables init.cpp --
? clang-tidy --checks=-*,cppcoreguidelines-init-variables init.cpp --fix --
clang-query的使用
通過clang-quey可以快速驗(yàn)證matcher的效果
matchers wiki: https://clang.llvm.org/docs/LibASTMatchersReference.html
? clang-query memory.c --? ? ?//查詢AST節(jié)點(diǎn)
? m functionDecl(isExpansionInMainFile())? ?//查詢main文件內(nèi)展開的函數(shù)節(jié)點(diǎn)
??m varDecl(isExpansionInMainFile())? ? //查詢main文件內(nèi)展開的變量節(jié)點(diǎn)
??set output detailed-ast? //設(shè)置輸出格式為詳細(xì)ast
再次搜索輸出變?yōu)閍st格式
? m functionDecl(isExpansionInMainFile(),hasName("foo"))? ?//查詢main文件內(nèi)展開的并包含函數(shù)名為foo的函數(shù)節(jié)點(diǎn)
可以通過多重條件精確匹配到合適的節(jié)點(diǎn)
??m functionDecl(isExpansionInMainFile(),matchesName("f"))? ?//查詢main文件內(nèi)展開的并函數(shù)名以字符"f"開頭的函數(shù)節(jié)點(diǎn)
? m callExpr(callee(functionDecl(hasName("malloc")))) //查找函數(shù)名為malloc的函數(shù)調(diào)用
實(shí)現(xiàn)一個(gè)可以檢查malloc(free)和修改malloc(free)的check
? cd to/clang-tools-extra/clang-tidy
? ./add_new_check.py misc change-malloc (添加check)
? Rebuild …
? clang-tidy --list-checks –checks=* | grep change?–查看是否新增成功
? 修改自定義的check實(shí)現(xiàn)檢查malloc的代碼邏輯
通過函數(shù)名字坟漱,找到需要對(duì)應(yīng)的函數(shù)調(diào)用節(jié)點(diǎn),代碼如下:
通過重載ChangeMallocCheck函數(shù)過濾出來的提示節(jié)點(diǎn)更哄,和自動(dòng)fix目標(biāo)代碼
? clang-tidy --checks=-*,misc-change-malloc malloc.c --
將malloc和free函數(shù)的告警信息并打印出來
? clang-tidy --checks=-*,misc-change-malloc malloc.c --fix --
將malloc和free函數(shù)的告警修復(fù)信息打印出來芋齿,
并自動(dòng)修復(fù)該告警
新增一個(gè)clangtidy check自定義類別
1.clang-tools-extra/clang-tidy/ClangTidyForceLinker.h
修改ClangTidyForceLinker.h腥寇,增加learn模塊鏈接
2.clang-tools-extra/clang-tidy/CMakeLiest.txt
修改CMakelist,添加learn模塊到編譯腳本
3.創(chuàng)建learn相關(guān)文件夾
創(chuàng)建learn模塊的文檔 觅捆、check赦役、test文件夾,否則會(huì)報(bào)錯(cuò)惠拭。
cd?~/llv/cl/llvm-project/clang-tools-extra/
mkdir -p checkers/learn? ??
mkdir -p ../test/clang-tidy/checkers/learn
mkdir -p ../docs/clang-tidy/checks/learn
4.創(chuàng)建clang-tools-extra/clang-tidy/learn/CMakeLists.txt文件(可以從MPI模塊拷貝一份扩劝,然后修改刪減)
修改learn模塊的編譯配置,mpi? --> learn
4.創(chuàng)建clang-tools-extra/clang-tidy/learn/LearnTidyModule.cpp文件(可以從MPI模塊拷貝一份职辅,然后修改刪減)
修改learn模塊總接口文件LearnTidyModule.cpp,負(fù)責(zé)管理本模塊的checks聂示,mpi? --> learn
5. 新增checker 類別成功
.
6. 測(cè)試新增checker功能
刪除一個(gè)類別
新增類別的逆向操作域携,刪除所做修改即可,此處不再實(shí)測(cè)鱼喉。
參考網(wǎng)站:
Clang AST簡介 - https://clang.llvm.org/docs/IntroductionToTheClangAST.html
? 匹配Clang AST - https://clang.llvm.org/docs/LibASTMatchers.html
? AST Matcher 參考 - https://clang.llvm.org/docs/LibASTMatchersReference.html
? Stephen Kelly’s 博客 - https://devblogs.microsoft.com/cppblog/author/stkellyms/,
https://steveire.wordpress.com/
? llvm 教學(xué)視頻 - https://github.com/vabridgers/LLVM-Virtual-Tutorial-2020.git
? 編譯數(shù)據(jù)庫參考 compile_commands.json - https://sarcasm.github.io/notes/dev/compilationdatabase.html
? 已實(shí)現(xiàn)的clang-tidy checks 列表 https://clang.llvm.org/extra/clangtidy/checks/list.html