Linux内核工具--Sparse
Sparse诞生于2004年,是由Linux之父开发的,目的就是提供一个静态检查代码的工具,从而减少Linux内核的隐患。起始,在Sparse之前已经有了一个不错的代码静态检查工具(SWAT),只不过这个工具不是免费软件,使用上有一些限制。所以Linus自己开发了一个静态检查工具。
版本: linux4.4.166
参考文档:Documentation/sparse.txt
Sparse通过gcc的扩展属性__attribute__以及自己定义的__context__来对代码进行静态检查。
__xxx双下划线开头的宏,表示编译器相关的一些属性设置
1 |
|
file: include/linux/compiler.h
1 |
file: tools/include/linux/types.h
| 宏名称 | 定义 | 说明 |
|---|---|---|
| __bitwise | __attribute__((bitwise)) | 确保变量是相同的位方式(比如 bit-endian, little-endiandeng) |
| __user | __attribute__((noderef, address_space(1))) | 指针地址必须在用户地址空间 |
| __kernel | __attribute__((noderef, address_space(0))) | 指针地址必须在内核地址空间 |
| __iomem | __attribute__((noderef, address_space(2))) | 指针地址必须在设备地址空间 |
| __safe | __attribute__((safe)) | 变量可以为空 |
| __force | __attribute__((force)) | 变量可以进行强制转换 |
| __nocast | __attribute__((nocast)) | 参数类型与实际参数类型必须一致 |
| __acquires(x) | __attribute__((context(x, 0, 1))) | 参数x 在执行前引用计数必须是0,执行后,引用计数必须为1 |
| __releases(x) | __attribute__((context(x, 1, 0))) | 与__acquires(x)相反 |
| __acquire(x) | __context__(x, 1) | 参数x的引用计数+1 |
| __release(x) | __context__(x, 1) | 与__acquire(x)相反 |
| __cond_lock(x,c) | ((c) ? ({ __acquire(x); 1; }) : 0) | 参数c 不为0时,引用计数 + 1, 并返回1 |
其中
__acquires(x)和__releases(x),__acquire(x)和__release(x)必须配对使用,都和锁有关,否则Sparse会发出警告
Sparse 在编译内核中的使用
1 | make C=1 检查所有重新编译的代码 |
如果进行
-Wbitwise的检查,需要定义#define __CHECK_ENDIAN__,可以通过CF进行传参
1 make C=2 CF="-D__CHECK_ENDIAN__"
示例
1 | static int |
在编译阶段检查锁,防止死锁.
参考
- 内核工具 – Sparse 简介
- what-does-static-int-function-acquires-releases-mean