内核工具 – Sparse 简介
一、Sparse 介紹
Sparse 誕生于 2004 年, 是由linux之父開發(fā)的, 目的就是提供一個(gè)靜態(tài)檢查代碼的工具, 從而減少linux內(nèi)核的隱患。內(nèi)核代碼中還有一個(gè)簡略的關(guān)于 Sparse的說明文件: Documentation/sparse.txt。Sparse通過 gcc 的擴(kuò)展屬性 __attribute__ 以及自己定義的 __context__ 來對代碼進(jìn)行靜態(tài)檢查。
|
宏名稱 |
宏定義 |
檢查點(diǎn) |
| __bitwise | __attribute__((bitwise)) | 確保變量是相同的位方式(比如 bit-endian, little-endiandeng) |
| __user | __attribute__((noderef, address_space(1))) | 指針地址必須在用戶地址空間 |
| __kernel | __attribute__((noderef, address_space(0))) | 指針地址必須在內(nèi)核地址空間 |
| __iomem | __attribute__((noderef, address_space(2))) | 指針地址必須在設(shè)備地址空間 |
| __safe | __attribute__((safe)) | 變量可以為空 |
| __force | __attribute__((force)) | 變量可以進(jìn)行強(qiáng)制轉(zhuǎn)換 |
| __nocast | __attribute__((nocast)) | 參數(shù)類型與實(shí)際參數(shù)類型必須一致 |
| __acquires(x) | __attribute__((context(x, 0, 1))) | 參數(shù)x 在執(zhí)行前引用計(jì)數(shù)必須是0,執(zhí)行后,引用計(jì)數(shù)必須為1 |
| __releases(x) | __attribute__((context(x, 1, 0))) | 與 __acquires(x) 相反 |
| __acquire(x) | __context__(x, 1) | 參數(shù)x 的引用計(jì)數(shù) + 1 |
| __release(x) | __context__(x, -1) | 與 __acquire(x) 相反 |
| __cond_lock(x,c) | ((c) ? ({ __acquire(x); 1; }) : 0) | 參數(shù)c 不為0時(shí),引用計(jì)數(shù) + 1, 并返回1 |
二、Sparse 使用方法
1. __bitwise 的使用
/* include/sound/core.h */ typedef int __bitwise snd_device_type_t;
2. __user 的使用
如果使用了 __user 宏的指針不在用戶地址空間初始化, 或者指向內(nèi)核地址空間, 設(shè)備地址空間等等, Sparse會(huì)給出警告.
/* arch/score/kernel/signal.c */ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
3. __kernel 的使用
如果使用了 __kernel 宏的指針不在內(nèi)核地址空間初始化, 或者指向用戶地址空間, 設(shè)備地址空間等等, Sparse會(huì)給出警告.
/* arch/s390/lib/uaccess_pt.c */ memcpy(to, (void __kernel __force *) from, n);
4. __iomem 的使用
如果使用了 __iomem 宏的指針不在設(shè)備地址空間初始化, 或者指向用戶地址空間, 內(nèi)核地址空間等等, Sparse會(huì)給出警告.
/* file:arch/microblaze/include/asm/io.h */ static inline unsigned char __raw_readb(const volatile void __iomem *addr)
5. __nocast 的使用
使用了__nocast修飾的參數(shù)的類型必須和實(shí)際傳入的參數(shù)類型一致才行,否則Sparse會(huì)給出警告.
/* fs/xfs/support/ktrace.c */ ktrace_alloc(int nentries, unsigned int __nocast sleep)
6. __acquires __releases __acquire __release的使用
這4個(gè)宏都是和鎖有關(guān)的, __acquires 和 __releases 必須成對使用, __acquire 和 __release 必須成對使用, 否則Sparse會(huì)給出警告。
三、補(bǔ)充
1. Sparse 在編譯內(nèi)核中的使用
用 Sparse 對內(nèi)核進(jìn)行靜態(tài)分析非常簡單.
# 檢查所有內(nèi)核代碼 make C=1 檢查所有重新編譯的代碼 make C=2 檢查所有代碼, 不管是不是被重新編譯
2. Sparse除了能夠用在內(nèi)核代碼的靜態(tài)分析上, 其實(shí)也可以用在一般的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 就會(huì)報(bào)錯(cuò) */
return 0;
}
如果安裝了 Sparse, 執(zhí)行靜態(tài)檢查的命令如下:
$ 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
總結(jié)
以上是生活随笔為你收集整理的内核工具 – Sparse 简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习----Xavier初始化方法
- 下一篇: Linux之创建777权限的文件