|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 mytomorrow 于 2019-9-17 20:21 编辑 3 I6 [- @; @ l8 z, [& z' _$ W
* v5 E1 B: ]- n+ ^( S X" pSparse是内核代码静态分析工具, 能够帮助我们找出代码中的隐患.
7 Q/ ?, c3 C3 {; R5 `
+ S ]- ]4 { o6 Z: H主要内容:! z# G- g* ^6 ~: b7 K/ U
+ D* z% i M8 M7 _' }2 P- Sparse 介绍
- Sparse 使用方法
- Sparse 在编译内核中的使用
- 补充
+ B: ^( n) k8 _( I l % Z$ B# g! X5 Y4 t/ ~- ]+ v+ Y
1. Sparse 介绍
/ D, b7 |9 [) y S7 E' x2 l
4 u% C% v* \- S1 F; ZSparse 诞生于 2004 年, 是由linux之父开发的, 目的就是提供一个静态检查代码的工具, 从而减少linux内核的隐患.( F& J4 W: `3 v2 }* f9 `
; S4 q; C) z) E8 P其实在Sparse之前, 已经有了一个不错的代码静态检查工具("SWAT"), 只不过这个工具不是免费软件, 使用上有一些限制.: a% q9 A" x$ k! f: Y
6 b( _/ y; G8 ~/ [' p1 r所以 linus 还是自己开发了一个静态检查工具.
; X+ \/ L/ [. p1 P
. {$ Y$ J% Z' w; P具体可以参考这篇文章(2004年的文章了): Finding kernel problems automatically! L4 U0 R6 D8 ~ K6 T( W7 \, [* B
" ?! R7 P1 j* e6 F+ {7 Q5 r1 Q c3 Q" z9 Q' d# `: L' o8 d
Sparse相关的资料非常少, 关于它的使用方法我也是网上查找+自己实验得出来的." n9 _2 }7 z" L+ O3 y& |
0 U( l! N0 W! G e) ?
内核代码中还有一个简略的关于 Sparse的说明文件: Documentation/sparse.txt/ ~! l! I7 c- j q0 a
3 S+ o @( ^( Y; K k! ?% Q8 W7 I, A# B
Sparse通过 gcc 的扩展属性 __attribute__ 以及自己定义的 __context__ 来对代码进行静态检查.
$ A) S$ t; G! P% ?" y5 J& s1 G' f( s: Q: Y2 k" G
这些属性如下(尽量整理的,可能还有些不全的地方):8 l6 Z3 H0 l' _" T, N
3 a0 W) i8 m+ S2 l
宏名称 | 宏定义 | 检查点 | __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 | % ~( d3 M3 j/ E, W4 |3 O2 O \- }
9 }: @$ U2 Q8 G1 m" e
其中 __acquires(x) 和 __releases(x), __acquire(x) 和 __release(x) 必须配对使用, 否则 Sparse 会给出警告
, N) h/ X8 C. ]5 S) {1 f) j! U0 v! u8 z. ^8 s( P; S
注: 在Fedora系统中通过 rpm 安装的 sparse 存在一个小bug.
; K+ w2 h% e- M; y! M1 R# x* R' ?8 D' r" r: ]) v
# @: x" S$ k: m6 Y( `$ K2 O5 l0 z0 S. ~
|
|