内核工具 – Sparse 简介

一、Sparse 介绍

Sparse 诞生于 2004 年, 是由linux之父开发的, 目的就是提供一个静态检查代码的工具, 从而减少linux内核的隐患。内核代码中还有一个简略的关于 Sparse的说明文件: Documentation/sparse.txt。Sparse通过 gcc 的扩展属性 __attribute__ 以及自己定义的 __context__ 来对代码进行静态检查。

宏名称

宏定义

检查点

__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

 

二、Sparse 使用方法

1. __bitwise 的使用

/* include/sound/core.h */
typedef int __bitwise snd_device_type_t;

2. __user 的使用

如果使用了 __user 宏的指针不在用户地址空间初始化, 或者指向内核地址空间, 设备地址空间等等, Sparse会给出警告.

/* arch/score/kernel/signal.c */
static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)

3. __kernel 的使用

如果使用了 __kernel 宏的指针不在内核地址空间初始化, 或者指向用户地址空间, 设备地址空间等等, Sparse会给出警告.

/* arch/s390/lib/uaccess_pt.c */
memcpy(to, (void __kernel __force *) from, n);

4. __iomem 的使用

如果使用了 __iomem 宏的指针不在设备地址空间初始化, 或者指向用户地址空间, 内核地址空间等等, Sparse会给出警告.

/* file:arch/microblaze/include/asm/io.h */
static inline unsigned char __raw_readb(const volatile void __iomem *addr)

5. __nocast 的使用

使用了__nocast修饰的参数的类型必须和实际传入的参数类型一致才行,否则Sparse会给出警告.

/* fs/xfs/support/ktrace.c */
ktrace_alloc(int nentries, unsigned int __nocast sleep)

6. __acquires __releases __acquire __release的使用

这4个宏都是和锁有关的, __acquires 和 __releases 必须成对使用, __acquire 和 __release 必须成对使用, 否则Sparse会给出警告。

 

三、补充

1. Sparse 在编译内核中的使用

用 Sparse 对内核进行静态分析非常简单.

# 检查所有内核代码
make C=1 检查所有重新编译的代码
make C=2 检查所有代码, 不管是不是被重新编译

2. Sparse除了能够用在内核代码的静态分析上, 其实也可以用在一般的C语言程序中.

复制代码
#include <stdio.h>

#define __acquire(x) __context__(x,1)
#define __release(x) __context__(x,-1)

int main(int argc, char *argv[])
{
    int lock = 1;
    __acquire(lock);
    /* ... */
    __release(lock); /* 注释掉这一句 sparse 就会报错 */
    return 0;
}
复制代码

如果安装了 Sparse, 执行静态检查的命令如下:

$ sparse -a sparse_test.c 
sparse_test.c:15:5: warning: context imbalance in 'main' - wrong count at exit

 

参考:https://www.cnblogs.com/wang_yb/p/3575039.html

 

posted on   Hello-World3  阅读(960)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2019-03-22 C++问题汇总

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示