C C 記憶體問題檢查利器 Purify (二)

2021-08-21 22:45:52 字數 4527 閱讀 3345

假設我們現在有這樣一段程式:

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所能檢測到的記憶體資訊表:

記憶體資訊

描述

錯誤等級

abr

array 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的支援比較少,而且有一種洩漏是由於執行過程中不斷增長但是在程式結束的時候釋放的...