2.2. 命令行使用:scan-build 和 CodeChecker¶
本文档提供有关从命令行在整个项目上运行静态分析器的指南。CodeChecker 和 scan-build 是用于在多个文件(翻译单元)上使用 CSA 的两个 CLI 工具。两者都提供了一种驱动分析器、检测编译标志和生成报告的方法。CodeChecker 维护得更为积极,它提供用于处理流行编译器的多个版本的启发式算法,并且还附带基于 Web 的 GUI 用于查看、过滤、分类和抑制结果。因此,如果您需要上述任何功能,或者只是需要更一般的可定制性,建议使用 CodeChecker。
2.2.1. CodeChecker 和 scan-build 的比较¶
静态分析器最初旨在作为 GUI 工具供 XCode IDE 使用。它的目的是在程序中查找有问题的执行路径,而查看非交互式标准输出很难理解这些路径。但是,可以从命令行调用静态分析器以获取分析结果,然后稍后在图形界面中交互式地查看它们。以下工具通常用于从命令行运行分析器。这两个工具都是包装脚本,用于驱动分析以及 Clang 编译器的底层调用
- scan-build 是一种旧的简单命令行工具,它在编译项目时将静态分析器警告作为 HTML 文件发出。您可以在 Web 浏览器中查看分析结果。
适用于只需要在桌面上查看静态分析结果的个人开发人员,或者是在非常简单的协作环境中。
适用于所有主要平台(Windows、Linux、macOS),并且在许多 Linux 发行版中都可用作软件包。
不支持跨翻译单元分析。
- CodeChecker 是一种驱动程序和 Web 服务器,它根据需要在您的项目上运行静态分析器,并维护一个问题数据库。
非常适合在协作环境中管理大量的静态分析器警告。
通常比 scan-build 功能更丰富。
支持增量分析:结果可以存储在数据库中,后续分析运行可以进行比较,以列出新添加的缺陷。
跨翻译单元 (CTU) 分析 在 Linux 上通过 CodeChecker 获得完全支持。
也可以运行 clang-tidy 检查器。
开源,但不在树外,即不是 LLVM 项目的一部分。
2.2.2. scan-build¶
scan-build 是一种命令行实用程序,允许用户在执行常规构建(从命令行)时在其代码库上运行静态分析器。
2.2.2.1. 它是如何工作的?¶
在项目构建期间,当编译源文件时,静态分析器也会同时对其进行分析。
构建完成后,结果将通过 Web 浏览器显示给用户。
2.2.2.2. 它适用于任何构建系统吗?¶
scan-build 对您如何构建代码了解甚少。它的工作原理是覆盖 CC
和 CXX
环境变量,以(希望)将您的构建更改为使用“假”编译器,而不是通常用于构建项目的编译器。此假编译器执行 clang
或 gcc
(取决于平台)来编译您的代码,然后执行静态分析器来分析您的代码。
这种“穷人插值”在许多情况下都能很好地工作,但在其他情况下却会失败。请参考此页面上的信息,了解如何充分利用 scan-build,其中包括当上述技巧无法使用时如何使其工作。
在 Web 浏览器中查看静态分析器结果
2.2.2.3. 基本用法¶
scan-build
的基本用法旨在保持简单:只需将“scan-build”放在构建命令前面即可
$ scan-build make
$ scan-build xcodebuild
在第一种情况下,scan-build
分析了使用 make
构建的项目的代码,而在第二种情况下,scan-build
分析了使用 xcodebuild
构建的项目。
以下是调用 scan-build
的一般格式
$ scan-build [scan-build options] <command> [command options]
在操作上,scan-build
会将所有后续选项传递给 <command> 来真正运行 <command>。例如,可以将 -j4
传递给 make
以在 4 个内核上进行并行构建
$ scan-build make -j4
在几乎所有情况下,scan-build
不会尝试解释构建命令后的选项;它只是将它们传递过去。一般来说,scan-build
应该支持并行构建,但不支持 分布式构建。
还可以使用 scan-build
分析特定文件
$ scan-build gcc -c t1.c t2.c
此示例将导致分析文件 t1.c
和 t2.c
。
2.2.2.4. 适用于 Windows 用户¶
Windows 用户必须安装 Perl 才能使用 scan-build。
scan-build.bat
脚本允许您以与上述基本用法部分中描述相同的方式启动 scan-build。若要从任意位置调用 scan-build,请将包含 scan-build.bat 的文件夹的路径添加到 PATH 环境变量中。
如果您在使用 MinGW/MSYS 运行 scan-build 时遇到意外的编译/制作问题,以下信息可能会有所帮助
如果您在使用 Windows cmd 中的 MSYS make 构建时遇到意外的
"fatal error: no input files"
,请尝试以下解决方案之一:- 使用 MinGWmingw32-make
而不是 MSYSmake
,并将 MSYS 的路径从 PATH 中排除,以防止mingw32-make
使用 MSYS 实用程序。MSYS 实用程序依赖于 MSYS 运行时,不打算从 Windows cmd 运行。具体来说,当传递用于执行时,使用反斜杠引用的 makefile 命令可能会严重损坏。- 从 sh shell 运行make
$ scan-build [scan-build options] sh -c "make [make options]"
如果您在使用 GNU Make 3.81 时遇到
"Error : *** target pattern contains no `%'"
,请尝试使用其他版本的 make。
2.2.2.5. 其他选项¶
如上所述,可以将额外选项传递给 scan-build
。这些选项位于构建命令之前。例如
$ scan-build -k -V make
$ scan-build -k -V xcodebuild
以下是部分有用选项
-o:HTML 报告文件的目标目录。将根据需要创建子目录来表示分析器的单独“运行”。如果未指定此选项,则将在
/tmp
中创建一个目录来存储报告。-h (或无参数):显示所有
scan-build
选项。-k, –keep-going:在指定的构建命令中添加“继续执行”选项。此选项当前支持
make
和xcodebuild
。这是一个便捷选项;可以使用构建选项直接指定此行为。-v:来自 scan-build 和分析器的详细输出。 第二个和第三个“-v”会提高详细程度,这对于针对分析器提交错误报告非常有用。
-V:构建命令完成后,在 Web 浏览器中查看分析结果。
–use-analyzer Xcode (或) –use-analyzer [clang 路径]:
scan-build
使用相对于自身的“clang”可执行文件进行静态分析。可以使用此选项通过使用 Xcode(在 OS X 上)或 PATH 中打包的“clang”来覆盖此行为。
可以通过运行 scan-build
并省略参数来获取所有选项的完整列表。
2.2.2.6. scan-build 的输出¶
scan-build 的输出是一组 HTML 文件,每个文件代表一个单独的错误报告。将生成单个 index.html
文件来查看所有错误。然后,您只需在 Web 浏览器中打开 index.html
即可查看错误报告。
HTML 文件的生成位置由传递给 scan-build
的 -o 选项指定。如果没有指定 -o,则将在 /tmp
中创建一个目录来存储这些文件(scan-build
将打印一条消息告诉您它们在哪里)。如果您希望在构建完成后立即查看报告,请将 -V 传递给 scan-build
。
2.2.2.7. 推荐的用法指南¶
本节介绍一些有关运行分析器的建议。
2.2.2.8. 始终在项目的“调试”配置中分析项目¶
大多数项目都可以在启用断言的“调试”模式下构建。静态分析器会拾取断言以修剪不可行的路径,在某些情况下,这可以极大地减少工具发出的误报(虚假错误报告)数量。
另一个选择是使用 scan-build 工具的 --force-analyze-debug-code
标志,这将自动启用断言。
2.2.2.9. 调试 scan-build 时使用详细输出¶
scan-build
接受一个 **-v** 选项来输出有关其操作的详细信息;两个 **-v** 选项会输出更多信息。将 scan-build
的输出重定向到文本文件(确保重定向标准错误)对于提交针对 scan-build
或分析器的错误报告非常有用,因为我们可以看到传递给分析器的确切选项(和文件)。为了获得更易懂的日志,不要进行并行构建。
2.2.2.10. 通过 scan-build 运行 ‘./configure’¶
如果要分析的项目使用 autoconf 生成的 configure
脚本,则可能需要通过 scan-build
运行 configure
脚本才能分析项目。
示例:
$ scan-build ./configure
$ scan-build --keep-cc make
configure
也需要通过 scan-build
运行的原因是 scan-build
通过插入编译器来扫描源文件。此插入目前由 scan-build
临时设置环境变量 CC
为 ccc-analyzer
来完成。程序 ccc-analyzer
就像一个假的编译器,将它的命令行参数转发给编译器以执行常规编译,并将它们转发给 clang
以执行静态分析。
运行 configure
通常会生成带有硬编码编译器路径的 makefile,通过 scan-build
运行 configure
会将该路径设置为 ccc-analyzer
。
2.2.2.11. 分析 iPhone 项目¶
从概念上讲,用于 iPhone 应用程序的 Xcode 项目几乎与用于桌面应用程序的项目相同。**scan-build** 也可以分析这些项目,但用户经常会遇到从命令行构建 iPhone 项目的问题,因为他们需要采取一些额外的准备步骤(例如,设置代码签名)。
2.2.2.12. 建议:使用“构建并分析”¶
分析 iPhone 项目的最简单方法是使用 Xcode 中的 分析功能(基于静态分析器)。用户可以在菜单中直接分析他们的项目,而无需进行大多数后面描述的设置。
本网站上提供了说明,介绍如何使用分析器的开源版本来替换捆绑在 Xcode 中的版本。
2.2.2.13. 直接使用 scan-build¶
如果你想在 iPhone 项目中使用 **scan-build**,请牢记以下几点
在
Debug
配置中分析你的项目,方法是使用 Xcode 将其设置为你的配置,或者将-configuration Debug
传递给xcodebuild
。使用
Simulator
作为你的基本 SDK 来分析你的项目。可以在针对设备时分析你的代码,但这在使用 Xcode 的构建并分析功能时要容易得多。检查你的代码签名 SDK 是否也设置为模拟器 SDK,并确保此选项设置为
Don't Code Sign
。
请注意,你可以在不修改项目的情况下完成大部分操作。例如,如果你的应用程序面向 iPhoneOS 2.2,你可以从命令行以以下方式运行 **scan-build**
$ scan-build xcodebuild -configuration Debug -sdk iphonesimulator2.2
或者,如果你的应用程序面向 iPhoneOS 3.0
$ scan-build xcodebuild -configuration Debug -sdk iphonesimulator3.0
2.2.2.14. 问题:使用正确的编译器¶
请记住,**scan-build** 通过使用编译器编译项目并使用 clang
分析项目来分析你的项目。该脚本使用简单的启发式方法来确定应该使用哪个编译器(默认情况下在 Darwin 上使用 clang
,在其他平台上使用 gcc
)。在分析 iPhone 项目时,**scan-build** 可能会选择错误的编译器,而不是 Xcode 用于构建项目的编译器。例如,这可能是因为你的系统上可能安装了多个版本的编译器,尤其是在你为 iPhone 进行开发时。
在编译你的应用程序以在模拟器上运行时,确保 **scan-build** 找到了 gcc/clang
的正确版本非常重要。否则,你可能会看到奇怪的构建错误,这些错误只在运行 scan-build
时才会发生。
**scan-build** 提供了 --use-cc
和 --use-c++
选项来硬编码 scan-build 应该用于构建代码的编译器。请注意,虽然你主要对分析你的项目感兴趣,但请记住,运行分析器与构建密切相关,无法编译代码意味着它将无法完全分析(如果有的话)。
如果你不确定 Xcode 使用哪个编译器来构建你的项目,尝试运行 xcodebuild
(不使用 **scan-build**)。你应该会看到 Xcode 使用的编译器的完整路径,并将其用作 --use-cc
的参数。
2.2.3. CodeChecker¶
2.2.3.1. 基本用法¶
按照此处的说明安装 CodeChecker:CodeChecker 安装指南。
创建编译数据库。如果你使用 cmake,则将 -DCMAKE_EXPORT_COMPILE_COMMANDS=1
参数传递给 cmake。Cmake 将创建一个 compile_commands.json
文件。如果你有基于 Makefile 或类似的构建系统,则可以使用 CodeChecker 的帮助来记录构建命令
make clean
CodeChecker log -b "make" -o compile_commands.json
分析你的项目
CodeChecker analyze compile_commands.json -o ./reports
查看分析结果。在命令行中打印详细结果
CodeChecker parse --print-steps ./reports
或在浏览器中查看详细结果
CodeChecker parse ./reports -e html -o ./reports_html
firefox ./reports_html/index.html
可选:将分析结果存储在数据库中
mkdir ./ws
CodeChecker server -w ./ws -v 8555 &
CodeChecker store ./reports --name my-project --url http://localhost:8555/Default
可选:在你的 Web 浏览器中管理(分类、抑制)结果
firefox http://localhost:8555/Default
2.2.3.2. 详细用法¶
有关扩展文档,请参阅 CodeChecker 的官方网站!