Categories: C/C++

Cppcheck:C/C++ 靜態程式碼分析工具使用教學與範例

介紹如何在 Linux 中使用 Cppcheck 靜態程式碼分析工具檢查,偵測 C/C++ 程式的臭蟲。

Cppcheck 是一個適用於 C/C++ 程式碼的靜態分析工具,可以偵測程式碼中的臭蟲(bugs)以及不合理的異常程式結構,其設計原則為低偽陽性(false positives),亦可用於非標準的語法結構(例如嵌入式專案)。

安裝 Cppcheck

若在 Linux 中可以使用各種套件管理工具來安裝 Cppcheck:

# Ubuntu/Debian Linux 安裝 Cppcheck
sudo apt-get install cppcheck

# Fedora Linux 安裝 Cppcheck
sudo yum install cppcheck

# macOS 安裝 Cppcheck
brew install cppcheck

若是 Windows 作業系統,則可從 Cppcheck 的官方網站下載 MSI 安裝檔案進行安裝。

使用 Cppcheck 檢測程式碼

假設我們有一個含有臭蟲的 C 語言原始碼檔案 source1.c 內容如下:

/* 含有臭蟲的 C 語言原始碼 */
int main() {
  char a[10];
  a[10] = 0;
  return 0;
}

我們可以利用 cppcheck 指令工具來檢測 C 語言原始碼中的臭蟲或漏洞:

# 檢測 C 語言原始碼
cppcheck source1.c
Checking source1.c ...
[source1.c:3]: (error) Array 'a[10]' accessed at index 10, which is out of bounds.

經過 Cppcheck 檢測之後,發現操作 a 陣列時超出邊界,這是 C 語言常見的臭蟲。

完整檢測

Cppcheck 預設只會進行基本的檢測,若要啟用其他附加性的檢測功能,可以使用 --enable 指令要啟用的檢測功能:

# 啟用所有附加檢測
cppcheck --enable=all source1.c

# 啟用 performance 與 portability 附加檢測
cppcheck --enable=performance,portability source1.c

Cppcheck 可用的檢測功能類型有:

  • all:所有檢測。
  • warning:警告訊息。
  • style:程式碼風格訊息,包含 performanceportability
  • performance:效能訊息。
  • portability:可移植性。
  • information:資訊訊息。
  • unusedFunction:檢查未使用函數。
  • missingInclude:檢查遺失的 include 檔案。

詳細的說明可以參考 cppcheck 的說明:

# 參數說明,可查詢可用之附加檢測名稱
cppcheck --help

# 列出所有檢測項目
cppcheck --doc

# 列出所有錯誤訊息
cppcheck --errorlist

若要對 source1.c 這個 C 語言原始碼檔案進行完整檢測,則可執行:

# 進行完整檢測
cppcheck --enable=all source1.c
Checking source1.c ...
[source1.c:3]: (error) Array 'a[10]' accessed at index 10, which is out of bounds.
[source1.c:3]: (style) Variable 'a' is assigned a value that is never used.

遞迴檢測

若在執行 cppcheck 時直接指定原始碼的目錄,就會對整個目錄與子目錄下所有的 C/C++ 程式碼進行檢測:

# 遞迴檢測指定目錄下所有原始碼
cppcheck /path/to/project

排除目錄

若要排除指定的目錄,可以使用 -i 參數指定目錄的路徑或名稱:

# 排除指定 samples 目錄
cppcheck -i /path/to/project/samples /path/to/project

# 排除所有 samples 目錄
cppcheck -i samples /path/to/project

輸出至檔案

Cppcheck 會將錯誤訊息輸出至標準錯誤(standard error),若要將錯誤訊息儲存至檔案,可以將標準錯誤導向至檔案:

# 遞迴檢測目前目錄下所有原始碼,輸出至 error.txt
cppcheck . 2> error.txt

不確定問題

Cppcheck 的設計原則是低偽陽性(false positives),也就是只顯示很確定的問題,如果不是很確定是否有問題的部分,預設則是不顯示。

如果需要 Cppcheck 連同不確定的部分都輸出,可以加上 --inconclusive 參數:

# 連同不確定問題一起輸出
cppcheck --enable=all --inconclusive source1.c

Include 搜尋路徑

若要指定 C/C++ 語言的 include 檔案搜尋路徑,可以使用 -I 參數指定路徑:

# 指定 include 搜尋路徑
cppcheck -I inc1/ -I inc2/ source.cpp

多執行緒

Cppcheck 支援多執行緒(multi-thread)的平行檢測,可以大幅提升檢測速度。

若要使用多執行緒的平行檢測,可以使用 -j 指定執行續數量:

# 以 4 條執行緒平行檢測
cppcheck -j 4 /path/to/project

XML 格式輸出

若要讓 Cppcheck 以 XML 格式輸出錯誤報表,可以加上 --xml 參數:

# 以 XML 格式輸出
cppcheck --xml source1.c
<?xml version="1.0" encoding="UTF-8"?>
<results version="2">
    <cppcheck version="1.82"/>
    <errors>
Checking source1.c ...
        <error id="arrayIndexOutOfBounds" severity="error" msg="Array &apos;a[10]&apos; accessed at index 10, which is out of bounds." verbose="Array &apos;a[10]&apos; accessed at index 10, which is out of bounds." cwe="119">
            <location file="source1.c" line="3" info="Array index out of bounds"/>
        </error>
    </errors>
</results>

參考資料

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

9 個月 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

9 個月 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

9 個月 ago

Windows 使用 TPM 虛擬智慧卡保護 SSH 金鑰教學與範例

本篇介紹如何在 Windows...

10 個月 ago

Linux 以 Shamir’s Secret Sharing 分割保存金鑰教學與範例

介紹如何在 Linux 中使用...

11 個月 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

11 個月 ago