Linux内核开发工具之Sparse

概述

Sparse 是我们用于 Linux 内核开发的一种语义解析器和静态分析工具。它可用于查找内核代码中一些潜在的问题。

Sparse 语义解析器提供了一个编译器前端,能够解析大部分 ANSI C 代码以及许多 GCC 扩展;此外,它还包含一组示例编译器后端,其中包括一个名为 Sparse 的静态分析器。Sparse 提供了一组注解,旨在传达有关类型的语义信息,例如指针指向何种地址空间,或某个函数获取或释放哪些锁。

最初由 Linus Torvalds 于 2003 年开始开发,目标是解决诸如用户地址空间指针与内核地址空间指针混用等问题。

官方文档: https://sparse.docs.kernel.org
内核中的文档: https://docs.kernel.org/dev-tools/sparse.html

获取与安装

可以从官方git仓库直接拉取最新的版本:

git clone git://git.kernel.org/pub/scm/devel/sparse/sparse.git

然后可以使用git checkout vxxx切到最新的稳定版分支进行编译安装。

也可以直接下载release版本的压缩包:https://www.kernel.org/pub/software/devel/sparse/dist/

有了源码之后编译安装很简单:

make
make install

它将会被默认安装到 ~/bin目录。

如果需要支持llvm,则要保证 llvm 彻底完全安装正确,不然可能会报如下错误:

sparse-llvm.c:6:10: fatal error: llvm-c/Core.h: 没有那个文件或目录
    6 | #include <llvm-c/Core.h>
      |          ^~~~~~~~~~~~~~~
compilation terminated.

简单使用

要为内核开发使用 sparse,只需在 make 命令中传递 C=2 参数即可。例如,要为 mac80211 开发启用 sparse,应使用:

make C=2 M=net/mac80211/

这将强制检查所有相应的源文件(无论文件是否被重新编译都会对其使用 sparse 工具)。若仅检查将要重新编译的文件,可使用 C=1 参数:

make C=1 M=net/mac80211/

如果你已经编译了内核,或使用过 C=2 进行过检查,再用后一种方式C=1可以更快地检查完,缩短检查时间。

make 的可选变量 CHECKFLAGS 可以用来向 sparse 工具传递参数。编译系统会自动向 sparse 工具传递 -Wbitwise 参数。

需要注意的是,静态分析工具可能会产生误报。在尝试修复错误和警告之前,务必仔细评估它们的准确性!!!