根本工具 – Sparse 简介

2.9 __cond_lock 的使用

本条宏有点尤其, 因为尚未 __cond_unlock 之类的宏和它对应.

之所以有这些宏的来头能够参见:
http://yarchive.net/comp/linux/sparse.html 最终一段.

那几个宏的来源清楚了, 不过干吗这一个宏里面还要调用一回 __acquire(x)?
小编也不是很驾驭, 在网上找了遥遥无期也没找到, 何人能指教的话非凡感激!!!

 

2.2 __user 的使用

比方利用了 __user 宏的指针不在用户地址空间开头化,
只怕指向内核地址空间, 设备地址空间等等, Sparse会给出警告.

基本代码中的例子:

/* 内核版本:v2.6.32.61  file:arch/score/kernel/signal.c 45行 */
static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)

 

2.5 __safe 的使用

使用了 __safe修饰的变量在运用前没有看清它是或不是为空(null),
Sparse会给出警告.

自小编参考的根本版本(v2.6.32.61) 中的全部内核代码都未曾应用 __safe,
估算或然是出于随着gcc版本的翻新,

gcc已经会对那种景色提交警告, 所以没有要求用Sparse去反省了.

 

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

用 Sparse 对根本进行静态分析10分简单.

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

 

 

2.7 __nocast 的使用

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

水源代码中的例子:

/* 内核版本:v2.6.32.61  file:fs/xfs/support/ktrace.c 55行 */
ktrace_alloc(int nentries, unsigned int __nocast sleep)

 

  • Sparse 介绍
  • Sparse 使用办法
  • Sparse 在编译内核中的使用
  • 补充

4. 补充

Sparse除了可以用在根本代码的静态分析上, 其实也得以用在形似的C语言程序中.

诸如上边的小例子:

/******************************************************************************
 * @file    : sparse_test.c
 * @author  : wangyubin
 * @date    : Fri Feb 28 16:33:34 2014
 * 
 * @brief   : 测试 sparse 的各个检查点
 * history  : init
 ******************************************************************************/

#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);
    /* TODO something */
    __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

 

Sparse相关资料可以参见wiki: Sparse
wiki

2.1 __bitwise 的使用

根本作用就是确保水源使用的整数是在相同的位方式下.

在基础代码根目录下 grep -r ‘__bitwise’,
会发现基本代码中过多地方都使用了这一个宏.

对此利用了这几个宏的变量, Sparse
会检查这一个变量是还是不是平素在一如既往种位格局(big-endian,
little-endian或其余)下被使用,

比方此变量在四个位艺术下被运用了, Sparse 会给出警告.

根本代码中的例子:

/* 内核版本:v2.6.32.61  file:include/sound/core.h 51行 */
typedef int __bitwise snd_device_type_t;

 

2.4 __iomem 的使用

只要利用了 __iomem 宏的指针不在设备地址空间初步化,
大概指向用户地址空间, 内核地址空间等等, Sparse会给出警告.

基础代码中的例子:

/* 内核版本:v2.6.32.61  file:arch/microblaze/include/asm/io.h 22行 */
static inline unsigned char __raw_readb(const volatile void __iomem *addr)

 

2.6 __force 的使用

使用了__force修饰的变量能够展开强制类型转换, 没有使用
__force修饰的变量举行强制类型转换时, Sparse会给出警告.

基础代码中的例子:

/* 内核版本:v2.6.32.61  file:arch/s390/lib/uaccess_pt.c 180行 */
memcpy(to, (void __kernel __force *) from, n);

 

2.3 __kernel 的使用

即使使用了 __kernel 宏的指针不在内核地址空间初阶化,
只怕指向用户地址空间, 设备地址空间等等, Sparse会给出警告.

根本代码中的例子:

/* 内核版本:v2.6.32.61  file:arch/s390/lib/uaccess_pt.c 180行 */
memcpy(to, (void __kernel __force *) from, n);

 

2.8 __acquires __releases __acquire __release的使用

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

 

 

Sparse是内核代码静态分析工具, 能够帮助大家找出代码中的隐患.

1. Sparse 介绍

Sparse 诞生于 二零零一 年, 是由linux之父开发的,
目的就是提供二个静态检查代码的工具, 从而裁减linux内核的隐患.

其实在Sparse从前, 已经有了2个正确的代码静态检查工具(“SWAT”),
只可是那个工具不是免费软件, 使用上有一些限制.

因而 linus 依然友好开销了多个静态检查工具.

切实可以参见那篇作品(二〇〇三年的篇章了): Finding kernel problems
automatically

 

Sparse相关的资料万分少, 关于它的行使办法自身也是网上搜寻+自个儿尝试得出来的.

水源代码中还有2个简短的关于 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

其中 __acquires(x) 和 __releases(x), __acquire(x) 和
__release(x) 必须配对使用, 否则 Sparse 会给出警告

 

: 在Fedora系统中通过 rpm
安装的 sparse 存在3个小bug.

即选拔时会报出 error: unable to open ’stddef.h’ 的谬误,
最好从友好源码编译安装 sparse.

参考: http://wangcong.org/blog/archives/504

 

首要内容:

2. Sparse 使用方法