<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      內核工具 – Sparse 簡介

      Sparse是內核代碼靜態分析工具, 能夠幫助我們找出代碼中的隱患.

       

      主要內容:

      • Sparse 介紹
      • Sparse 使用方法
      • Sparse 在編譯內核中的使用
      • 補充

       

      1. Sparse 介紹

      Sparse 誕生于 2004 年, 是由linux之父開發的, 目的就是提供一個靜態檢查代碼的工具, 從而減少linux內核的隱患.

      其實在Sparse之前, 已經有了一個不錯的代碼靜態檢查工具("SWAT"), 只不過這個工具不是免費軟件, 使用上有一些限制.

      所以 linus 還是自己開發了一個靜態檢查工具.

      具體可以參考這篇文章(2004年的文章了): Finding kernel problems automatically

       

      Sparse相關的資料非常少, 關于它的使用方法我也是網上查找+自己實驗得出來的.

      內核代碼中還有一個簡略的關于 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 存在一個小bug.

      即使用時會報出 error: unable to open ’stddef.h’ 的錯誤, 最好從自己源碼編譯安裝 sparse.

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

       

      2. Sparse 使用方法

      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.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.3 __kernel 的使用

      如果使用了 __kernel 宏的指針不在內核地址空間初始化, 或者指向用戶地址空間, 設備地址空間等等, Sparse會給出警告.

      內核代碼中的例子:

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

       

      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.5 __safe 的使用

      使用了 __safe修飾的變量在使用前沒有判斷它是否為空(null), Sparse會給出警告.

      我參考的內核版本(v2.6.32.61) 中的所有內核代碼都沒有使用 __safe, 估計可能是由于隨著gcc版本的更新,

      gcc已經會對這種情況給出警告, 所以沒有必要用Sparse去檢查了.

       

      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.7 __nocast 的使用

      使用了__nocast修飾的參數的類型必須和實際傳入的參數類型一致才行,否則Sparse會給出警告.

      內核代碼中的例子:

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

       

      2.8 __acquires __releases __acquire __release的使用

      這4個宏都是和鎖有關的, __acquires 和 __releases 必須成對使用, __acquire 和 __release 必須成對使用, 否則Sparse會給出警告.

       

      2.9 __cond_lock 的使用

      這個宏有點特別, 因為沒有 __cond_unlock 之類的宏和它對應.

      之所以有這個宏的原因可以參見: http://yarchive.net/comp/linux/sparse.html 最后一段.

      這個宏的來源清楚了, 但是為什么這個宏里面還要調用一次 __acquire(x)? 我也不是很清楚, 在網上找了好久也沒找到, 誰能指教的話非常感謝!!!

       

      3. Sparse 在編譯內核中的使用

      用 Sparse 對內核進行靜態分析非常簡單.

      # 檢查所有內核代碼
      make C=1 檢查所有重新編譯的代碼
      make C=2 檢查所有代碼, 不管是不是被重新編譯

       

      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

      posted @ 2014-03-01 14:18  wang_yb  閱讀(16267)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 国产美女久久精品香蕉| 亚洲欧美高清在线精品一区二区| 国产三级精品三级在线观看| 久久久av男人的天堂| 亚洲熟妇一区二区三个区| 亚洲天堂伊人久久a成人| 亚洲色欲在线播放一区 | 欧洲精品色在线观看| 国产一区二区三区禁18| 国产福利在线观看免费第一福利| 欧美猛少妇色xxxxx| 国产超碰人人做人人爰| 日韩高清国产中文字幕| 国产午夜精品一区二区三区不卡| 又污又黄又无遮挡的网站| 国产福利在线观看免费第一福利| 中卫市| 久久亚洲av成人无码软件| 亚洲午夜成人精品电影在线观看| 十八禁午夜福利免费网站| 思思久99久女女精品| 国产肉丝袜在线观看| 国内极度色诱视频网站| 视频专区熟女人妻第二页| 激情综合网址| 国产精品久久久久7777| 亚洲区成人综合一区二区| 久久国产精品伊人青青草| 麻豆亚洲精品一区二区| 国产伦精品一区二区三区| 狠狠噜天天噜日日噜无码| 亚洲夂夂婷婷色拍WW47| 国产一区二区不卡自拍| 色国产视频| 精品乱人码一区二区二区| 欧美黑人XXXX性高清版| 欧美成人看片黄A免费看| 国产三级精品福利久久| 亚洲欧美精品一中文字幕| 国产高潮刺激叫喊视频| 成在线人视频免费视频|