• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            興海北路

            ---男兒仗劍自橫行
            <2008年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            統(tǒng)計

            • 隨筆 - 85
            • 文章 - 0
            • 評論 - 17
            • 引用 - 0

            常用鏈接

            留言簿(6)

            隨筆分類

            隨筆檔案

            收藏夾

            全是知識啊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            代碼覆蓋率的測試工具 -- gcov

            代碼覆蓋率的測試工具 -- gcov

            2009-03-25 09:47

            簡介
            在這章里,我們將會探討gcov實用程序,并且了解一下如何使用gcov來幫助測試與支持軟件配置與優(yōu)化。我們將會了解如何使用gcov來構(gòu)建軟件,并且理解他所提供的各種數(shù)據(jù)類型。最后,我們將探討當(dāng)執(zhí)行保險測試時要避免的事情。

            gcov是什么?
            我們從gcov可以為我們做什么開始。gcov是一個保險測試工具。當(dāng)構(gòu)建一個程序時,gcov會監(jiān)視一個程序的執(zhí)行,并且會標(biāo)識出執(zhí)行了哪一行源碼,哪 一行沒有執(zhí)行。更進(jìn)一步,gcov可以標(biāo)識出某一行源執(zhí)行的次數(shù),這對于執(zhí)行配置很有用(程序在哪里花費了大多數(shù)的時間)。因為gcov可以分辨出哪一行 沒有執(zhí)行,這對于保險測試工具是很有用的。
            讓我們來看一下如何為gcov的使用準(zhǔn)備鏡像。我們將會在接下來的部分提供更為詳細(xì)的gcov的選項,所以這里只是作為一個介紹。我們將將會使用下面的所列的bubblesort的源碼:
            1:       #include <stdio.h>
            2:
            3:       void bubbleSort( int list[], int size )
            4:       {
            5:         int i, j, temp, swap = 1;
            6:
            7:         while (swap) {
            8:
            9:           swap = 0;
            10:
            11:           for ( i = (size-1) ; i >= 0 ; i-- ) {
            12:
            13:             for ( j = 1 ; j <= i ; j++ ) {
            14:
            15:               if ( list[j-1] > list[j] ) {
            16:
            17:                 temp = list[j-1];
            18:                 list[j-1] = list[j];
            19:                 list[j] = temp;
            20:                 swap = 1;
            21:
            22:               }
            23:
            24:             }
            25:
            26:           }
            27:
            28:         }
            29:
            30:       }
            31:
            32:       int main()
            33:       {
            34:         int theList[10]={10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
            35:         int i;
            36:
            37:         /* Invoke the bubble sort algorithm */
            38:         bubbleSort( theList, 10 );
            39:
            40:         /* Print out the final list */
            41:         for (i = 0 ; i < 10 ; i++) {
             42:           printf("%d\n", theList[i]);
            43:         }
            44:
            45:       }
            gcov程序?qū)c編譯器工具鏈一起使用。這就意味著我們將要在其上進(jìn)行保險測試的鏡像必須用一個特殊的選項集合進(jìn)行編譯。下面是我們用來演示編譯bubbleSort.c的命令:
                gcc bubblesort.c -o bubblesort -ftest-coverage -fprofile-arcs
            當(dāng)我們執(zhí)行生成的程序時會生成一些包含關(guān)于程序的相關(guān)數(shù)據(jù)的文件。gcov程序?qū)褂眠@些文件來報告數(shù)據(jù)并且向開發(fā)者提供相應(yīng)的信息。當(dāng)指定 -ftest-coverage選項時會為每一個源碼生成兩個文件。這些文件會使用.bb.bbg作為擴(kuò)展名,并且用這些文件來重組每一個可執(zhí)行程序的 程序流圖。對于-fprofile-arcs,將會生成一個包含每一個指令分支的執(zhí)行計數(shù)的以.da為擴(kuò)展名的文件。這些文件會在執(zhí)行以后與源碼文件一起 使用,來標(biāo)識源碼的執(zhí)行行為。

            使用gcov程序
            現(xiàn)在我們準(zhǔn)備好了我們的程序鏡像了,讓我們繼續(xù)我們其余的部分。運行我們的程序就會生成我們在前面所討論的數(shù)據(jù)集文件。然后我們使用我們希望進(jìn)行檢測的源碼運行gcov程序。如下面所示:
            $ ./bubblesort
                ...
            $ gcov bubblesort.c
            100.00% of 17 source lines executed in file bubblesort.c
            Creating bubblesort.c.gcov.
            這告訴我們在我們的例子程序中所有的源碼行至少都執(zhí)行了一次。我們可以通過查看所生成的bubblesort.c.gcov文件來了解每一源碼行所實際運行的次數(shù)。如下面所示:
                    -:    0:Source:bubblesort.c
                    -:    0:Graph:bubblesort.gcno
                    -:    0:Data:bubblesort.gcda
                    -:    0:Runs:1
                    -:    0:Programs:1
                    -:    1:#include <stdio.h>
                    -:    2:void bubbleSort(int list[],int size)
                    1:    3:{
                    1:    4:    int i,j,temp,swap=1;
                    4:    5:    while(swap)
                    -:    6:    {
                    2:    7:   swap=0;
                   22:    8:   for(i=(size-1);i>=0;i--)
                    -:    9:   {
                  110:   10:        for(j=1;j<=i;j++)
                    -:   11:        {
                   90:   12:       if(list[j-1]>list[j])
                    -:   13:       {
                   45:   14:            temp=list[j-1];
                   45:   15:            list[j-1]=list[j];
                   45:   16:            list[j]=temp;
                   45:   17:            swap=1;
                    -:   18:       }
                    -:   19:        }
                    -:   20:   }
                    -:   21:    }
                    1:   22:}
                    -:   23:int main()
                    1:   24:{
                    1:   25:    int theList[10]={10,9,8,7,6,5,4,3,2,1};
                    -:   26:    int i;
                    -:   27:    /*Invoke the buble sort algorithm*/
                    1:   28:    bubbleSort(theList,10);
                    -:   29:
                    -:   30:    /*print out the final list*/
                   11:   31:    for(i=0;i<10;i++)
                    -:   32:    {
                   10:   33:   printf("%d\n",theList[i]);
                    -:   34:    }
                    1:   35:    return 0;
                    -:   36:}
            現(xiàn)在讓我們來看一下其中的一些關(guān)鍵點,看一下他所提供的內(nèi)容。第一列顯示了源碼中每一行源碼所執(zhí)行的次數(shù)。在一些情況下,執(zhí)行次數(shù)并沒有提供。這些只是并不會影響代碼的簡單C源碼元素。
            這些計數(shù)可以提供一些關(guān)于程序執(zhí)行的信息。例如,測試的第12行執(zhí)行了90次,而14-17行的代碼只是執(zhí)行了45次。這告訴我們當(dāng)這個函數(shù)調(diào)用了90次,真正成功的僅是45次。換句話說,大部分的測試時間浪費在兩個元素的交換上。這是由于測試數(shù)據(jù)的順序所造成的。
            從這里我們可以看到代碼段中最常執(zhí)行的部分就是排序算法的內(nèi)循環(huán)部分。這是因為由于退出測試第10行要比第12行執(zhí)行的次數(shù)多一些。
            查看分支概率
            我們也可以使用-b選項來查看程序的分支數(shù)據(jù)。這個選項會輸出程序中每一個分支的頻度與相應(yīng)的摘要。例如,我們使用-b選項來執(zhí)行gcov命令:
            $ gcov -b bubblesort.c
            100.00% of 17 source lines executed in file bubblesort.c
            100.00% of 12 branches executed in file bubblesort.c
            100.00% of 12 branches taken at least once in file bubblesort.c
            100.00% of 2 calls executed in file bubblesort.c
            Creating bubblesort.c.gcov.
            所生成的bubblesort.c.gcov文件如下所示。
                    -:    0:Source:bubblesort.c
                    -:    0:Graph:bubblesort.gcno
                    -:    0:Data:bubblesort.gcda
                    -:    0:Runs:1
                    -:    0:Programs:1
                    -:    1:#include <stdio.h>
                    -:    2:void bubbleSort(int list[],int size)
            function bubbleSort called 1 returned 100% blocks executed 100%
                    1:    3:{
                    1:    4:    int i,j,temp,swap=1;
                    4:    5:    while(swap)
            branch 0 taken 67%
            branch 1 taken 33% (fallthrough)
                    -:    6:    {
                    2:    7:   swap=0;
                   22:    8:   for(i=(size-1);i>=0;i--)
            branch 0 taken 91%
            branch 1 taken 9% (fallthrough)
                    -:    9:   {
                  110:   10:        for(j=1;j<=i;j++)
            branch 0 taken 82%
            branch 1 taken 18% (fallthrough)
                    -:   11:        {
                   90:   12:       if(list[j-1]>list[j])
            branch 0 taken 50% (fallthrough)
            branch 1 taken 50%
                    -:   13:       {
                   45:   14:            temp=list[j-1];
                   45:   15:            list[j-1]=list[j];
                   45:   16:            list[j]=temp;
                   45:   17:            swap=1;
                    -:   18:       }
                    -:   19:        }
                    -:   20:   }
                    -:   21:    }
                    1:   22:}
                    -:   23:int main()
            function main called 1 returned 100% blocks executed 100%
                    1:   24:{
                    1:   25:    int theList[10]={10,9,8,7,6,5,4,3,2,1};
                    -:   26:    int i;
                    -:   27:    /*Invoke the buble sort algorithm*/
                    1:   28:    bubbleSort(theList,10);
            call    0 returned 100%
                    -:   29:
                    -:   30:    /*print out the final list*/
                   11:   31:    for(i=0;i<10;i++)
            branch 0 taken 91%
            branch 1 taken 9% (fallthrough)
                    -:   32:    {
                   10:   33:   printf("%d\n",theList[i]);
            call    0 returned 100%
                    -:   34:    }
                    1:   35:    return 0;
                    -:   36:}
            從這里我們可看到這與上面的文件相類似,但是這一次每一個分支點都用他們的頻度進(jìn)行了標(biāo)示。
            分支點依賴于目標(biāo)結(jié)構(gòu)建指令集。第12行是一個簡單的if語句,所以有一個分支點。在這里我們可以注意到這是50%,這通過我們前面觀察程序的執(zhí)行次數(shù)可 以看出。其他的分支點有一些難于分析。例如,第7行是一個while語句,有兩個分支點。在X86匯編中,這一行分編譯成我們下面所看到的樣子:
            1:   cmpl        $0, -20(%ebp)
            2:   jne        .L4
            3:   jmp        .L1
            從這里我們可看出,swap變量與0進(jìn)行比較。如果他不等于0,就會跳轉(zhuǎn)到第2行,.L4。否則要跳轉(zhuǎn)到第3,.L1。第2行所示的分支概率為67%。 這是因為這一行執(zhí)行3次,但是jne只執(zhí)行了兩次。當(dāng)?shù)?/font>2行的jne并沒有執(zhí)行時,我們直勢頭跳轉(zhuǎn)到第3行。這只執(zhí)行一次,但是一旦執(zhí)行,程序就結(jié)束了。 所以分支1要花費100%的時間。
            所以分支概率在理解程序流時是要相當(dāng)有用的,但是要參考匯編需要理解分支點在哪里。
            不完整程序測試
            當(dāng)gcov計數(shù)一個測試并不是100%的程序時,并沒有執(zhí)行的行是標(biāo)記為####,而不是執(zhí)行次數(shù)。下面顯示的是一個由gcov創(chuàng)建的文件來顯示少于100%的測試。
            1:                #include <stdio.h>
            2:
            3:                int main()
            4:           1    {
            5:           1      int a=1, b=2;
            6:
            7:           1      if (a == 1) {
            8:           1        printf("a = 1\n");
            9:                  } else {
            10:      ######        printf("a != 1\n");
            11:                  }
            12:
            13:           1      if (b == 1) {
            14:      ######        printf("b = 1\n");
            15:                  } else {
            16:           1        printf("b != 1\n");
            17:                  }
            18:
            19:           1      return 0;
            20:                }
            當(dāng)這個程序運行時,gcov實用程序也會向標(biāo)準(zhǔn)輸出輸出相應(yīng)的信息。他會顯示可能執(zhí)行的源碼行的行數(shù)以及實際運行的百分比。
            $ gcov incomptest.c
            77.78% of 9 source lines executed in file incomptest.c
            Creating incomptest.c.gcov.
            $
            如果我們的例子程序有多個函數(shù),我們可以通過使用-f選項來查看每一個函數(shù)的執(zhí)行情況。如下面的我們以bubbleSort程序所進(jìn)行的演示:
            $ gcov -f bubblesort.c
            100.00% of 11 source lines executed in function bubbleSort
            100.00% of 6 source lines executed in function main
            100.00% of 17 source lines executed in file bubblesort.c
            Creating bubblesort.c.gcov.
            $
            gcov可用的選項
            gcov程序調(diào)用的格式為:
            gcov [options] sourcefile
             其可用的選項如下:
            選項           目的
            -v-version       打印版本信息
            -h,-help       打印幫助信息
            -b,-branch-probabilities向輸出文件輸出分支頻度
            -c,-branch-counts   打印分支計數(shù)而不是分支頻度
            -n,-no-output       不創(chuàng)建gcov輸出文件
            -l,-long-file-names   創(chuàng)建長文件名
            -f,-function-summaries   打印每一個函數(shù)的概要
            -o,-object-directory   .bb,.bbg,.da文件存放的目錄
            從上面這個表中,我們可以看到一個單個字符選項,以及一個長選項。當(dāng)從命令行中使用gcov命令時短選項是比較有用的,但是當(dāng)gcovMakefile的一個部分時,應(yīng)使用長選項,因為這更易于理解。
            當(dāng)了解gcov程序的版本信息時,可以使用-v選項。因為gcov是與一個指定的編譯器工具鏈聯(lián)系在一起的(實際上是由gcc工具鏈而構(gòu)建的),gcc版本與gcov的版本是相同的。
            gcov程序的簡介以及選項幫助可以用-h選項來進(jìn)行顯示。



            posted on 2010-01-03 12:03 隨意門 閱讀(2535) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久久免费观成人影院 | segui久久国产精品| 国产99久久九九精品无码| 久久久久亚洲精品中文字幕| 久久经典免费视频| 999久久久免费精品国产| 久久国产成人| 久久棈精品久久久久久噜噜| 99久久综合狠狠综合久久| 亚洲性久久久影院| 9191精品国产免费久久| 久久国内免费视频| 欧美久久久久久精选9999| 97久久精品午夜一区二区| 日本久久久久久久久久| 久久久91精品国产一区二区三区 | 久久精品九九亚洲精品| 性欧美大战久久久久久久| 久久国产精品99久久久久久老狼| 亚洲国产精品成人AV无码久久综合影院 | 免费精品国产日韩热久久| 久久久久久a亚洲欧洲aⅴ| 97精品伊人久久久大香线蕉 | 99久久国产主播综合精品| 亚洲狠狠婷婷综合久久蜜芽| 成人a毛片久久免费播放| 久久久精品2019免费观看| 国产成人综合久久精品红| 久久久久国产| 精品久久久久久无码人妻蜜桃| 欧美丰满熟妇BBB久久久| 超级碰碰碰碰97久久久久| 人妻少妇精品久久| 国产精品欧美久久久久天天影视 | 中文字幕无码av激情不卡久久| 久久精品这里热有精品| 久久99国产精品久久99果冻传媒| 久久精品中文无码资源站| 久久久久久午夜成人影院| 国产精品无码久久久久久| 国产精品99久久99久久久|