天天看點

clang靜态分析器

補充:centos7.8安裝llvm7

https://www.liangzl.com/get-article-detail-20723.html

clang 中文:

https://www.bookstack.cn/read/clang-llvm/clang-user-manual.md#MinGW-w64

clang以及clang靜态分析器的安裝,詳見本人另一篇部落格。

https://blog.csdn.net/weixin_43124861/article/details/102800113

靜态分析比較好的總結:https://blog.csdn.net/cayman_2015/article/details/81744879

關于靜态分析器和checker的更多實作細節,參見:http://clang-analyzer.llvm.org/checker_dev_manual.html

clang靜态分析網址: http://clang-analyzer.llvm.org/

clang靜态分析scan-build網址:http://clang-analyzer.llvm.org/scan-build.html

scan-build是當clang靜态分析作為單獨工具被調用時會用到。

1.靜态分析(分析bug和記憶體溢出等)

程式分析分為動态分析和靜态分析兩種,其中靜态分析是指不實際運作程式而通過詞法分析、文法分析、控制流、資料流等技術對源碼進行掃描分析,動态分析則相反。

1.clang靜态分析器介紹

1.1

馬尤爾·潘迪 (Mayur Pandey); 蘇尤葛·撒達 (Suyog Sarda). LLVM Cookbook中文版 (Kindle 位置 3047-3049). 電子工業出版社. Kindle 版本.

Clang靜态分析器是一種源代碼分析工具,可以查找C,C ++和Objective-C程式中的錯誤。它既可以作為獨立工具運作,也可以在Xcode中運作。 獨立工具是從指令行調用的,旨在與代碼庫的建構一起運作。該分析器是100%開源的,并且是Clang項目的一部分。

1.2

源代碼通過Clang文法分析後,生成了文法分析樹(AST),任務不同就有不同的效果:1、作為編譯器前端将AST翻譯成為IR;2、作為靜态分析工具對AST進行分析。

1.3

Clang自己定義了很多Checker,可以通過下面的指令行查出所有的checker,注意,每一種類型的bug,都有一種對應的checker。

>clang -cc1 -analyzer-checker-help
           
clang靜态分析器

下面是一些clang靜态分析器自帶的一些檢查器

clang靜态分析器

1.3

當需要對單個源檔案進行檢測時,使用下面的指令進行檢測:

>clang --analyze -Xanalyzer -analyzer-checker=
           

以上語句針對一般的單個檔案的小程式實用,

當需要對大型檔案進行分析的時候,就需要用到scan-buid這個自動化腳本,它是由perl語言編寫而成的,使用如下:

> scan-build [options] [build options]
           

例如:

scan-build --use-c++ /usr/bin/clang++--use-analyzer=/usr/bin/clang  -enable-checkeryourself.checker -k make
           

上面這條指令,–use-c++指定了使用的C++編譯器,

–use-analyzer指定使用的分析器,

-enable-checker指定需要使用到分析器,這個分析器可以是自己編寫的分析器,預設情況下scan-build會開啟一些核心的checker,可以通過指令檢視:

scan-build–use-analyzer=/usr/bin/clang -h

這就會列出所有的checker,其預設開啟的是前面會有"+"号,也可以使用-disable-checker關閉預設的checker。

檢測完成,可以使用scan-view檢視檢測的結果。

2.解釋scan-build

scan-build是LLVM的前端工具Clang所提供的靜态分析工具,Scan-build 是一個指令行工具,它能夠幫助使用者運作靜态分析器檢查他們的代碼, 找出代碼的缺陷。scan-build可以使用一個僞編譯器代替原來那個可以正常建構你的項目的編譯器。預設情況下,這個僞編譯器使用gcc來編譯你的代碼,然後執行靜态分析器進行代碼分析。

代碼結構分析與可視化。對代碼結構進行分析,并将控制流程圖和函數調用關系圖以圖形化形式顯示。其中控制流程圖針對單個函數,可清晰地了解函數的分支、跳轉和循環結構;函數調用關系圖針對一組函數,呈現函數間的調用與被調用關系。在查找軟體bug以及詳細設計文檔編寫中,利用此功能可提供極大友善。

3.clang靜态分析器–小實驗

實驗内容:以除零錯誤為例,展示clang靜态分器如何處理這個錯誤

實驗須知:實驗主要是通過 Clang 靜态 分析器 對 代碼 進行 靜态 分析。 它 基于 Clang 和 LLVM 建構, 它 使用 的 靜态 分析 引擎 是 一個 Clang 庫, 是以 具有 較 高的 可 重用 性, 并 能夠 在 不同 的 客戶 端 中 使用。(源于llvm cookbook中對clang靜态分析器的解釋)

3.1.

首先建立一個源檔案,源檔案内容如下所示。

這裡使用sublime編譯器,sublime安裝詳見本人另一篇部落格

sublime安裝: https://blog.csdn.net/weixin_43124861/article/details/102795557

sub sa.c
           
clang靜态分析器
clang靜态分析器

3.2

其次,執行以下代碼運作clang靜态分析器

clang -cc1 -analyze -analyzer-checker=core.DivideZero sa.c

clang分析-------------分析檢查器的名字-------------------------源檔案

clang -cc1 -analyze -analyzer-checker=core.DivideZero sa.c
           
clang靜态分析器

4.clang靜态分析器–工作原理

1)程式中的每一條肯能路徑都會被分析, 對于 每一種 類型 的 bug, 都有 一個 對應 的 checker。

2)執行 的 時候, 執行 軌迹 由 爆炸 圖( exploded graph) 來 表示, 每一個 ExplodedGraph 上 的 節點 稱為 ExplodedNode, 它 由 一個 ProgramState 對象( 表示 程式 的 抽象 狀态), 以及 一個 ProgramPoint 對象( 表示 程式 的 相應 位址), 所 組成。

3)在 建構 ProgramState 的 時候, 每個 checker 都會 連結 到 分析器 的 核心。 每次 分析 引擎 探測 一個 新的 語句 的 時候, 它 會 通知 每一個 注冊 的 checker 去 監聽 這個 語句, 給 它 報告 bug 或者 修改 語句 的 機會。

4)每一個 checker 則 會 注冊 不同 的 事件 和 回 調 函數, 例如 PreCall( 在 函數 調用 之前), DeadSymbols( 符号 失效) 等。 不同 的 事件 會 通知 不同 的 checker, 它們 也會 執行 不同 的 動作。

5)本實驗使 用了 除 零 checker, 它 會 報告 除 零 的 錯誤。 這個 checker 注冊 了 PreStmt 回 調, 在 語句 執行 之前 調用。 檢查 下一 條 語句 的 運算符, 如果 是 除法 運算符, 則 檢查 除數 是否 為 0, 如果 找到 可能 的 值 則 報告 bug。

6)checker與checker之間都是互相聯通的,一個checker會用到其他checker檢測。

關于靜态分析器和checker的更多實作細節,參見http://clang-analyzer.llvm.org/checker_dev_manual.html