假設我們現在有這樣一段程式:
hello.c
#include
#include
static char *helloworld = "hello, world";
main()
很明顯,這段程式中有記憶體上的錯誤,假設我們疏忽了這些錯誤,當我們使用purify進行測試時,我們會發現這段程式中的記憶體錯誤在purify下很容易就被找出來了。首先,我們要做的是使用purify編譯這段程式:
> purify gcc -g -o hello hello.c
instrumenting: cckc6pud.o linking
記得加上「-g」的選項,不然,purify不能顯示源程式。好了,現在在當前目錄下產生了可執行檔案——hello,在執行hello之前,我們還得注意,執行被purify編譯過的程式,有可能會出現x-windows,所以請注意設定display環境,如果你是在windows的telnet客戶端下執行,那麼你可以在windows下裝乙個叫做exceed的工具軟體,它可以方便地把x-window顯示在你的windows桌面上)
好了,我們現在執行hello程式,就可以看到下面的乙個視窗:
我們可以看到purify的報告中有兩個記憶體錯誤,乙個是abr(array bounds read)——陣列越界讀,乙個是12個位元組的memory leaked,展開小三角符號,我們可以看到更為詳細報告:
展開abr錯誤後,我們可以看到,abr錯誤的產生是由printf產生的,而產生錯誤的記憶體是mystr。通過觀察,我們馬上可以發現為會什麼會出現abr錯誤,原因是c/c++中的字串都是以「/0」結尾的,而我們分配字串時,應該要比實際長度多一,以存放結束符,而我們以後面呼叫的strncpy只拷貝了字串的有效內容,並沒有在字串最後加上乙個結束符。而系統呼叫printf輸出字串內容直至遇到結束符,所以當其訪問到12個長度時,還沒有發現結束,於是繼續向下訪問,於是就出現了abr錯誤。
好了,讓我們再來看看memory leaked的報告資訊:
我們可以看到,purify指出了那塊記憶體出現了記憶體洩露,洩露了多少個位元組。通過purify的報告,再加上我們對c/c++基礎的了解,我們立馬知道mystr是在堆上分配的記憶體,所以必須要我們自己手動釋放,檢視程式,我們發現我們忘了free ( mystr )。
好了,現在我們可以根據purify報告修改我們的程式了:
#include
#include
static char *helloworld = "hello, world";
main()
現在,我們再用purify重新編譯我們的程式,然後執行,我們可以看到purify會報告沒有任何的記憶體問題。其實,使用purify很簡單,在後面,我將對purify的各種常用特性做比較全面的闡述。
下面是purify所能檢測到的記憶體資訊表:
記憶體資訊
描述
錯誤等級
abrarray bounds read 陣列越界讀
3級abw
array bounds write 陣列越界寫
2級bsr
beyond stack read 越棧讀
3級bsw
beyond stack write 越棧寫
3級cor
core dump imminent 非法操作
1級fiu
file descriptors in use 檔案描述符被使用
4級fmm
freeing mismatched memory 釋放錯誤記憶體
2級fmr
free memory read 對已釋放記憶體讀
3級fmw
free memory write 對已釋放記憶體寫
2級fnh
freeing non heap memory 釋放非堆記憶體
2級fum
freeing unallocated memory 釋放了沒有分配的記憶體
2級ipr
invalid pointer read 非法指標讀
1級ipw
invalid pointer write 非法指標寫
1級maf
malloc failure 分配記憶體失敗
4級miu
memory in-use 記憶體正在使用
4級mlk
memory leak 記憶體洩露
3級mre
malloc reentrancy error remalloc錯
2級mse
memory segment error 記憶體段錯
3級npr
null pointer read 空指標讀
1級npw
null pointer write 空指標寫
1級par
bad parameter 錯誤的引數
3級plk
potential leak 潛在的記憶體洩露
3級sbr
stack array bounds read 棧陣列越界讀
3級sbw
stack array bounds write 棧數級越界寫
2級sig
signal 訊號
4級sof
stack overflow 棧溢位
3級umc
uninitialized memory copy 對未初始化的記憶體進行拷貝
3級umr
uninitialized memory read 對未初始化的記憶體讀
3級wpf
watchpoint free 釋放被監控的記憶體
4級wpm
watchpoint malloc 被監控的記憶體分配
4級wpn
watchpoint entry 被監控的記憶體
4級wpr
watchpoint read 被監控的記憶體讀
4級wpw
watchpoint write 被監控的記憶體寫
4級wpx
watchpoint exit 退出被監控的記憶體
4級zpr
zero page read 零頁面讀
1級zpw
zero page write 零頁面寫1級
1級:致命錯誤。 2級:危險錯誤。 3級:警告資訊 4級:提示資訊(非錯誤)
C C 記憶體問題檢查利器 Purify (二)
假設我們現在有這樣一段程式 hello.c include include static char helloworld hello,world main 很明顯,這段程式中有記憶體上的錯誤,假設我們疏忽了這些錯誤,當我們使用purify進行測試時,我們會發現這段程式中的記憶體錯誤在purify下很...
C C 檢查記憶體洩漏
最近剛換工作,還在試用期,分配給我的也都是些零碎的任務。前陣子領導扔給我乙個小專案,這個專案底層使用c 編寫的3d渲染引擎,然後用cli包裝了一下,提供給上層的c 呼叫。這個專案存在比較嚴重的記憶體洩漏問題,由於目前公司寫c 的人寥寥無幾,寫c 的又不太懂如何檢測c 的記憶體洩漏,領導就把這個小任務...
C C 記憶體洩漏檢查之經驗
c程式中最可怕的事情就是碰到記憶體洩漏或者記憶體錯誤,特別是對於大型的專案而言要去查乙個小小的記憶體洩漏可要花不少功夫的。目前已經有很多這方面的工具,比較著名的如rational purify,不過purify對linux的支援比較少,而且有一種洩漏是由於執行過程中不斷增長但是在程式結束的時候釋放的...