Sparse¶
Sparse 是一个用于 C 程序的语义检查器;它可以用来发现内核代码中许多潜在的问题。查看 https://lwn.net/Articles/689907/ 以获取关于 sparse 的概述;本文档包含一些特定于内核的 sparse 信息。关于 sparse 的更多信息(主要是关于其内部实现)可以在其官方页面 https://sparse.docs.kernel.org 找到。
使用 sparse 进行类型检查¶
“__bitwise” 是一个类型属性,所以你必须这样做
typedef int __bitwise pm_request_t;
enum pm_request {
PM_SUSPEND = (__force pm_request_t) 1,
PM_RESUME = (__force pm_request_t) 2
};
这使得 PM_SUSPEND 和 PM_RESUME 成为“按位”整数(之所以加上 “__force”,是因为 sparse 会对按位类型之间的转换发出警告,但在这种情况下,我们确实_确实_想要强制进行转换)。而且由于 枚举值 都是相同的类型,现在 “enum pm_request” 也将是该类型。
对于 gcc 而言,所有的 “__bitwise”/“__force” 相关内容都会被去掉,最终在 gcc 眼里它们看起来就像是普通的整数。
坦率地说,你并不需要 enum there。上述所有内容实际上只是归结为一个特殊的 “int __bitwise” 类型。
所以更简单的方法是直接这样做
typedef int __bitwise pm_request_t;
#define PM_SUSPEND ((__force pm_request_t) 1)
#define PM_RESUME ((__force pm_request_t) 2)
这样你就拥有了进行严格类型检查所需的所有基础设施。
一个小提示:常量整数 “0” 很特殊。你可以使用常量零作为按位整数类型,而 sparse 不会发出任何抱怨。这是因为 “bitwise”(顾名思义)旨在确保按位类型不会被混淆(小端序 vs 大端序 vs cpu 端序或其他),在这种情况下,常量 “0” 确实_非常_特殊。
获取 sparse¶
你可以从以下地址获取最新发布版本的压缩包(tarballs):https://linuxkernel.org.cn/pub/software/devel/sparse/dist/
或者,你也可以使用 git clone 获取 sparse 最新开发版本的快照
git://git.kernel.org/pub/scm/devel/sparse/sparse.git
获取源码后,只需执行
make
make install
以普通用户身份执行,它就会将 sparse 安装到你的 ~/bin 目录中。
使用 sparse¶
执行内核编译时带上 “make C=1” 参数,即可对所有重新编译的 C 文件运行 sparse,或者使用 “make C=2” 对所有文件运行 sparse,无论它们是否需要重新编译。如果你已经构建了内核,后者是检查整个代码树的快速方法。
可选的 make 变量 CF 可用于向 sparse 传递参数。构建系统会自动向 sparse 传递 -Wbitwise 参数。
注意,sparse 定义了 __CHECKER__ 预处理器符号。