像UNIX下的軟體,一般都會提供和别的應用程式的接口,像上面的生成文本檔案,也是給别的應用程式提供接口的一種方式。這裡,我們所要講述的是Purify的退出碼,我們知道程式都有退出碼,以提供給别的程式或作業系統自己運作的資訊。被Purify編譯過的程式,你可以通過指定-exit-status參數來告訴Purify是否用Purify的退出碼,如果這個參數值為yes,那麼表示使用Purify的退出碼,如果值為no則表示使用程式内的退出碼。
如果我們這樣設定:-exit-status=yes,那麼Purify的退出碼是這樣定義的:
記憶體錯誤種類
退出碼(按位或)
記憶體存取錯誤
0x40
記憶體洩露
0x20
潛在記憶體洩露
0x10
通過上表,我們可以知道,當-exit-status參數被打開後,程式的退出碼被Purify完全接管,如果程式中有記憶體錯誤,那麼退出碼所對應的位就會被置為1,這樣,我們可以用别的程式來調用Purify所編譯出來的程式,并根據其退出碼作相應的處理。
你可以在UNIX的Shell環境中使用Purify的一些參數和資訊,Purify為Shell提供了一些通配符之類的東西,隻要你使用 –run-at-exit參數。例如你有一個Shell程式想把Purify生的檔案拷貝到别的目錄中,或是你想根據Purify的報告中是否有記憶體錯誤進行下一步的行動。
下面有兩個表格,說明了一些Purify和Shell互動的參數:
有關記憶體出錯的資訊:
通配字元串
含義
%z
指明是否有記憶體錯誤或記憶體洩露。其值是“true”或“false”
%x
程式的退出狀态(如果是0,表示程式沒有調用exit函數)
%e
程式中記憶體通路錯誤的個數。
%E
程式中錯誤總數。
%l
記憶體洩露的位元組數。
%L
潛在記憶體洩露的位元組數。
有關程式運作的資訊:
%V
運作程式的全路徑(“/”被替換成了“_”)
%v
程式的名稱
%p
程式的進行ID
在使用Purify過程中,有兩種方法可以傳遞Purify的參數,一種就是在指令行上指明。另外一種是設定一個和Purify相關的環境變量:PURIFYOPTIONS。現在,我通過這個環境變量要舉一個例子,以說明上面表格中的參數在使用中的情況:
例如,如果我們這樣這置環境變量:(在C-Shell中)
setenv PURIFYOPTIONS '-run-at-exit="if %z ; then \
echo \"%v: %e errors, %l+%L bytes leaked.\" ; fi"'
當我們運作被Purify編譯過的程式後,會出現以下結果:
hello: 2 errors, 1+10 bytes leaked.
我們可以看到,由于hello程式出錯了,是以%z為“true”,是以Purify執行echo指令,其中,%v表示了程式名(hello),%e表示了錯誤的個數(2),%l表示了記憶體洩露的位元組數(1),%L表示了程式中有潛在可能的記憶體洩露位元組數(12)。
讓我們再來看兩個例子:
示例一:
指定Purify的參數為: -log-file=./%v.plog
示例二:
指定Purify的參數為: -view-file=/home/hchen/%V.pv
總這,這些有“%”的變量,都是Purify提供給作業系統Shell的,以供Shell程式設計使用的。
如果你的程式比較大,子產品也比較多,有時候出現的資訊非常的多,你程式中很可能有某段代碼産生了若幹個記憶體錯誤,是以,我們可以使用Purify的過濾器來讓Purify隻顯示某一種類的資訊,這樣友善我們進行問題的查找和排錯。
1、 在Purify的X-Window中設定資訊過濾,點選圖形界面中的菜單“Options” -–> “Suppressions”,将出現“Suppressions”對話框,如下所示:
我們可以看到在上面的對話框中,如果過濾Purify的報告資訊。當我們點選“Where to suppress”隻要,我們會看到有如下的五個選項:
l In Call Chain:表示在某個函數調用鍊中資訊。
l In File:表示隻報告在某個檔案中的資訊。
l In Library:表示隻報告在某個LIB檔案中的資訊。
l In Class:這是C++的,表示報告某個類的資訊。
l Everywhere:表示全部範圍内的資訊。
但是圖形界面中,Purify并沒有給我們提供一個選取檔案或LIB或類的對話框,我們隻能通過其文本文法來描述,接下來就讓我們來看一看,過濾Purify報告資訊的文本文法。
2、 我們可以使用Purify的過濾文法來要求Purify的過濾資訊。并把其存于.purify檔案中,這樣當我們的Purify起動後載入這個檔案,就可以達到過濾資訊的目的了。通過文本文法來設定過濾資訊比圖形界有更為強大的地方。下面還是來看看suppress的文法:
文法:
suppress <message-type> <function-call-chain>
unsuppress <message-type> <function-call-chain>
其中,suppress和unsuppress中關鍵字,分别表示過濾或不過濾。<message-type>指明要操作的消息,可以使用“*”做通配符,<function-call-chain>表示函數的調用鍊,調用的函數鍊用分号分隔,其同樣可以使用“*”做通配符,還可以使用“…”來表示無論中間是什麼。
還是來看幾個示例吧:
1) suppress AB*
表示過濾ABR和ABW錯誤。
2) suppress *W
表示過濾ABW、FMW、IPW、NPW、SBW、WPW和ZPW錯誤。
3) suppress ABR “libc*”
表示在所有以libc打頭的LIB檔案中過濾ABR資訊。
4) suppress ABR sortFunction; sort*; qsort; “libc*”
其表示,過濾ABR錯誤。過濾範圍是在sortFunction中,并且是在以libc開頭的函數庫檔案中,其調用鍊是qsort -> sort* -> sortFunction。換言之,隻要有“libc*”檔案中的函數調用了qsort,并且qsort調用了開頭為sort*的函數,并且這些函數調用了sortFunction,那麼,在這一個函數鍊中,不顯示ABR錯誤資訊。
5) suppress UMR tzsetWall;…; main
其表示,在tzsetWall函數中過濾URM資訊,隻要tzsetWall函數是被main函數間接調用的,無論有多遠,都不顯示UMR資訊。
6) suppress FNH Test: :Test
這是C++中使用的文法,表示在類Test所有的構造函數中過濾FNH資訊。如果要指明特定的函數,請加上其參數類型,如:suppress FNH Test::Test(const char*)。
注意,“…”文法表示調用鍊無論有多遠。當然,如果你設定了參數“-chain-length=6”,那麼,“…”隻能到6層函數調用,7層的就不管了。
在啟動Purify時,我們可以這樣來讀取.purify檔案:
% purify -suppression-file-names=".purify,.purify.sunos4,\
$HOME/purify_suppressions"
Purify會在下面的目錄中尋找這個檔案:
<purifyhome>/.purify
<purifyhome>/.purify.sunos4
$HOME/.purify
$HOME/.purify.sunos4
<progdir>/.purify
<progdir>/.purify.sunos4
$HOME/purify_suppressions
本文轉自 haoel 51CTO部落格,原文連結:http://blog.51cto.com/haoel/124670,如需轉載請自行聯系原作者