内核工具 – 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
總結
以上是生活随笔為你收集整理的内核工具 – Sparse 简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习----Xavier初始化方法
- 下一篇: 怎么创建具有真实纹理的CG场景岩石?