# CppCheck ##### 文章指令都是以「CLI」為主 ## 輸出參數調整 3. [文件](https://cppcheck.sourceforge.io/manual.pdf) cppcheck --xml --xml-version=2 --enable=all libzmq-master/ > OpenSourceResult.xml 2>&1 cppcheck-htmlreport --title=testHTML --file=report-basic2.xml --source-dir=. --report-dir=report/xml/index.xml sudo yum install -y cppcheck-htmlreport > 可以用 `cppcheck --help` 來查閱 ### 參數目錄 `--output-file=<file>` : 用來把檔案輸出保存到目標文件內 `--xml` : 以 XML 格式生成,主要用於自動化 `--enable=<check>` : 啟用指定的檢查類型(比如 style) `--disable=<check>` : 禁用指定的檢查類型(比如 performance) `--std=<standard>` : 選擇符合的 C 標準如: C++11 `--library=<file>` : 指定自定義 Library `--platform=<platform>` : 檢查在指定 OS 平台上的相容性 `--verbose` : 更加詳細的輸出(每個檢查訊息都有) `--quiet` : 最小化輸出,只有 Error 跟 Warning `--check-config` : 檢查 CppCheck 配置文件是否有錯,在執行前避免測試問題 ## 重點整理 靜態分析是不能全部錯誤都發現的 EX. Halo World - 執行指令 (如果指定的是 Floder 他會掃描內部全部 File) `cppcheck file1.c` - 產生結果示範 ``` Checking file1.c... [file1.c:4]: (error) Array 'a[10]' index 10 out of bounds ``` --- ### 資料夾過濾 `cppcheck --file-filter=<str>` 可以指定只掃描特定資料夾 `cppcheck -i <Path>`不想掃描的話 --- ### 輸出保存 `-cppcheck-build-dir=path` : 將分析信息保存在目標路徑,提高分析速度 `--output-file=<file>` : 把檔案輸出保存到目標文件內 --- ### 預先處理 如果使用 `--project` 的話,Cppcheck 會自動導入項目內的預處理器 如果不是的話,可能需要手動定義 --- ### 選擇掃描的平台類型 `--platform=<platform>` : 決定在指定 OS 平台上執行 默認使用本地 OS 配置執行,也可以使用 XML 來自定義平台配置 ![image](https://hackmd.io/_uploads/HJvbiMpEp.png) ### 掃描類型 `--enable=<check>` : 啟用指定的檢查類型(比如 style) `--disable=<check>` : 禁用指定的檢查類型(比如 performance) **類型如下:** 1. `style` : 程式碼風格,比如駝峰命名跟 Black 2. `performance` : 性能方面,不需要的循環與低效能代碼 3. `portability` : 對於各個平台的可疑值性 4. `information` :檢查 Code 的訊息 -> (Function call / Variable型別與作用區 / Code structure / Include file 名稱路徑) 5. `warning`: 非錯誤,而是有風險的部分。 6. `error`: 導致代碼運行失敗 7. `performance-...` : 指定特定性能問題,如多線程性能或是不必要拷貝。 8. `portability-..`: 移植性檢查的子類別,如 POSIX 函數的使用與負數索引。 --- ### 選擇掃描版本 `--std=<standard>` : 選擇標準 #### `--std=<standard>` 的版本 * c89: 使用 C89 標準 * c99: 使用 C99 標準 * c11: 使用 C11 標準 (default) * c++98:使用 C++98 標準。 * c++03:是 C++98 的修訂版。 * c++11:被稱為 C++0x,引入了許多新特性。(default) * c++14:對 C++11 進行了一些修訂和擴展。 * c++17:引入了更多的新功能和改進。 * c++20:C++17 的進一步擴展,引入了許多新特性。 ### Cppcheck build dir 使用 `--cppcheck-build-dir` 來執行 可以加快速度,已知且未修改的錯誤不會再次掃描,會從 build dir 叫出重新顯示 **重點**:如果使用 multiple threads 時,必須 Build Dir 才能執行 ### Suppressions 錯誤抑制 用來過濾掉某些錯誤的問題 **錯誤文字過濾** 範例 ``` [error id]:[filename]:[line] [error id]:[filename2] [error id] ``` 可以使用 –template=gcc 來抑制目標的 error id 而文件可以用 * 或 ? **以 CLI 操作** `cppcheck --suppress= memleak:src/file1.cpp src/` **同樣可以使用 XML 來自定義設置** `cppcheck --suppress-xml=suppressions.xml src/` **或是指定程式碼內的特定行數** `cppcheck --inline-suppr test.c` **還能過濾特定的 Format 內容** `cppcheck-suppress [aaaa, bbbb]` ### 回報格式-XML 指令如下 ``` cppcheck --xml file1.cpp ``` `Error 元素格式` * id : 錯誤的 id 與有效的符號名 * severity : 嚴重性 (warning/style/performance/portability/information) * msg: 簡短的錯誤訊息 * verbose: 更詳細的錯誤訊息 * inconclusive: 此錯誤訊息無法確定 * CWE: 弱點標準,只有知道錯誤訊息的 CWE ID 時才使用 **Location 元素格式** * file: 文件名稱,路徑可以相對或絕對 * file0: 文件的 Source Name * line: 行數 * info: 簡短訊息 ### 回報格式-Text OutPut 指令為: `cppcheck --template` 使用 VsCode 的模板 (Vs 限定) `cppcheck --template=vs samples/arrayIndexOutOfBounds/bad.c` 也可以使用 gcc 的模板 `cppcheck --template=gcc samples/arrayIndexOutOfBounds/bad.c` 也可以自定義單行 / 多行的模板,範例如下: ``` cppcheck --template="{file}:{line}: {severity}: {message}" samples/arrayIndexOutOfBounds/bad cppcheck --template="{file},{line},{severity},{id},{message}" samples/arrayIndexOutOfBounds/ ``` 他的選項有這些: * {file} * {line} * {column} * {callstack} * {inconclusive:text} * {inconclusive:inconclusive,} * {severity} * {message} * {id} * {code} * \t * \n * \r ### 使用 Addons - 分析 Cppcheck 文件的腳本,用來檢查兼容性與安全問題 - 有幾個內建的 addons,也可以自訂如 js 的腳本,比如下方範例 ``` { "script": "misra.py", "args": [ "--rule-texts=misra.txt" ] } ``` 1. misra .py :嵌入式系統用,不可修改,有準則用來避免代碼問題 1. y2038 .py :檢查 Linux 的安全系統(到 2038 年) 1. threadsafety .py :檢查 thread 的安全問題如多線程 執行方式: ``` cppcheck --addon=<addon> <Target-File> ``` ### 檢查 Library 如果使用外部的 Library 可能會偵測不到問題,需要手動加載 Library `--check-library` : 用來獲得幫助 `--library=<file>` : 指定自定義 Library ### 回報格式-HTML 31 頁 - 需要 Python 跟 pygments 才能實現 - 把 XML 轉成 HTML,利用內建的 htmlreport 實現 - 指令是這個: `htmlreport/cppcheck-htmlreport -h` - 相關參數如下: ``` Options: -h, --help show this help message and exit --file=FILE The cppcheck xml output file to read defects from. Default is reading from stdin. --report-dir=REPORT_DIR The directory where the html report content is written. --source-dir=SOURCE_DIR Base directory where source code files can be found. ``` - 執行範例如下: ``` ./cppcheck gui/test.cpp --xml 2> err.xml htmlreport/cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=. ``` --- ## 補充說明 ### 決定檢查詳不詳細,快不快速 - 詳細度有 Normal 跟 Exhaustive 兩種,預設是普通 - 詳細版本會花費明顯較長時間去檢查,切換指令如下 ``` --check-level=exhaustive. ``` - 而檢查的快速程度可以調整這個達到 - 如果是使用 GUI 會有更多且更有效的選項可以選擇 ``` --performance-valueflow-max-if-count ``` ### 如何 Import Project #### GUI `cppcheck --project=<Floder or File>` #### Cmake 先生成 Database| `cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON` 然後在執行|`cppcheck --project=compile_commands.json` #### Visual Studio `cppcheck --project=foobar.sln` 也可以更詳細 ``` cppcheck --project=foobar.sln "--project-configuration=Release|Win32" ``` ### verbose / 原本 / quiet 的差異 -- quiet : 最簡潔的輸出,只有基本的錯誤訊息跟警告訊息 -- nomoral: 基本的輸出 -- verbose: 比較詳細的輸出,除了錯誤訊息外可能還會有檢查的程式,錯誤的行數等等 # 與 SonarQube 的連動: 1. [GitHub 的 CppCheck Plugin](https://github.com/SonarQubeCommunity/sonar-cppcheck) 2. [手動添加的方式](https://blog.csdn.net/qq_15559817/article/details/100736498) ### Note 1. Build image (Auto) ( 開專案去 Build -> Dev7 ) 2. Sonarqube -> Cppcheck (C++) <- Plugun or rule (CE) <--- Docker Container (Sonqube 9.9.2) ## 實踐紀錄: [官方說明不支援 CppCheck (DEV版本)](https://community.sonarsource.com/t/developer-edition-with-cppcheck/23139) [Sonar-Scanner 設置](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/) ### 讓 C++ 專案在 Sonarqube 中執行 1. [X] 安裝 Sonarqube 2. [X] 安裝 Cxx Plugins 3. [X] 安裝 Host 端 Sonar-scanner-cli 4. [ ] 設定 sonar-project.properties 5. [ ] 設定好[C++額外的要求](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/languages/c-family/) ### 把 CppCheck 的 XML 結果在 Sonarqube 上展宴 1. [ ] 完成 Sonarqube C++ 執行條件 2. [ ] 設定 sonar-project.properties 3. [ ] 設定 Cppchck.path