<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 查找嵌入式C語(yǔ)言程序/軟件中的缺陷的多種技術(shù)

查找嵌入式C語(yǔ)言程序/軟件中的缺陷的多種技術(shù)

作者: 時(shí)間:2010-11-23 來(lái)源:網(wǎng)絡(luò ) 收藏


然后我們重新運行程序,將不會(huì )再報告任何內存錯誤。當我們把程序上載到目標板上時(shí),它似乎如我們預期那么在工作了。盡管如此,我們仍然有一些擔心。

我們僅到我們所執行的代碼路徑中的一個(gè)內存寫(xiě)溢出實(shí)例,我們憑什么能夠斷定我們尚未執行到的代碼就不會(huì )有內存寫(xiě)溢出錯誤了呢?如果我們檢查覆蓋率分析,我們就會(huì )發(fā)現reportSensorFailure()這個(gè)函數從未被執行到。我們有必要對這個(gè)函數進(jìn)行測試,但是具體如何進(jìn)行呢?建立一個(gè)調用該函數的單元測試用例就是一個(gè)不錯的辦法。

在單元測試中使用運行時(shí)內存監測:我們使用C++test的測試用例向導來(lái)創(chuàng )建一個(gè)測試用例的框架,并向其中添加一些測試代碼。然后運行該測試用例——以檢查上面提到的未經(jīng)測試的函數,同時(shí)打開(kāi)運行時(shí)內存監測功能。使用C++teST,全過(guò)程大約只需要數秒鐘。

結果標明該函數已經(jīng)被覆蓋到了,但同時(shí)也到了新的錯誤:

本文引用地址:http://dyxdggzs.com/article/151316.htm

我們的測試用例到了更多的內存相關(guān)錯誤。很顯然,當失敗處理函數被調用時(shí),我們的內存初始化存在問(wèn)題(空指針)。通過(guò)更進(jìn)一步的分析,我們發(fā)現在reportSensorValue()函數中存在函數調用順序錯誤。

finalize()函數先于printMessage()函數被調用,但是finalize()函數中釋放了printMessage()函數需要使用的內存。

void finalize()
{
if (messages) {
free(messages[0]);
free(messages[1]);
free(messages[2]);
}
free(messages);
}

將函數調用順序進(jìn)行修改后,我們重新運行程序。

這樣我們就解決了上面報告中的第一個(gè)錯誤?,F在我們再來(lái)分析報告中的第二個(gè)錯誤:即打印信息中的AccessViolatiONException。產(chǎn)生這個(gè)錯誤的原因是相應的消息列表未經(jīng)初始化。為了解決該問(wèn)題,我們在打印該信息前調用一次initialize()函數來(lái)對其進(jìn)行初始化。經(jīng)修改后的函數如下所示:

void reportSensorFailure()
{
initialize();
printMessage(ERROR, 0);
finalize();
}

當我們再次運行該測試用例時(shí),僅有一個(gè)任務(wù)被報告出來(lái):未經(jīng)驗證的單元測試用例(an unvalidated unit test case),這其實(shí)并不算一條錯誤。我們只需對輸出進(jìn)行一下驗證,以將該測試用例轉換為回歸測試。通過(guò)創(chuàng )建合適的斷言,C++test會(huì )自動(dòng)為我們完成這些步驟。

接下來(lái)我們再次運行整個(gè)程序。覆蓋率分析告訴我們幾乎整個(gè)程序都已經(jīng)被覆蓋到了,并且沒(méi)有發(fā)現任何內存錯誤。

這樣就結束了嗎?其實(shí)不然。雖然我們運行了整個(gè)程序并為未覆蓋到的函數創(chuàng )建了單元測試用例,但還是有一些路徑是沒(méi)有被覆蓋到的。我們仍然可以繼續創(chuàng )建單元測試用例,但是若指望通過(guò)這樣的方法來(lái)覆蓋程序中的所有路徑將耗費相當長(cháng)的時(shí)間?;蛘呶覀兪褂昧硗獾姆椒?,使用數據流分析來(lái)對這些路徑進(jìn)行模擬。

數據流分析

我們使用C++test的BugDetective來(lái)進(jìn)行數據流分析,BugDetective能模擬系統中的不同路徑并檢查這些路徑中是否存在潛在的問(wèn)題。進(jìn)行數據流分析后,我們得到如下結果:

仔細分析報告的結果,我們發(fā)現程序中存在一條未被覆蓋到的潛在路徑可能會(huì )造成在finalize()函數中出現兩次free的操作。在程序中,reportSensorValue()函數調用了finalize()函數,然后finalize()函數調用了free()。同時(shí),finalize()函數還會(huì )被mainLoop()函數調用。我們可以修改finalize()函數以使其更加智能化,從而修復這個(gè)問(wèn)題,修改后的代碼如下:

void finalize()
{
if (messages) {
free(messages[0]);
free(messages[1]);
free(messages[2]);
free(messages);
messages = 0;
}
}

現在我們再次運行數據流分析,得到的結果將只有兩個(gè)問(wèn)題:

這里我們可能使用了-1作為索引來(lái)訪(fǎng)問(wèn)了數組。這是由于整型變量index被設置的初始值為-1,并且存在一條可能通過(guò)if語(yǔ)句的路徑在未將該整型變量正確的進(jìn)行初始化之前便調用了printMessage()函數。運行時(shí)分析未檢查到這樣的一條路徑,并且該路徑很有可能在真實(shí)世界中永遠不可能被執行到。這就是靜態(tài)數據流分析相對于運真實(shí)運行時(shí)內存監測最主要的不足:數據流分析能檢查出潛在的路徑,這些路徑可能包含在程序實(shí)際執行過(guò)程中不會(huì )執行到或不存在的路徑。盡管如此,為了做到有備無(wú)患,我們刪除了上述的不必要的條件(value>=0)以修改這個(gè)潛在的錯誤。

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>