由於缺少boundschecker這樣的得力助手,我們用 wxDev-C++ 編程的時候萬一不小心訪問記憶體越界了,可能會發現不了,
往往使程式得到錯誤的運行結果。如果越界越到了windows明令禁止的地區(比如地址為0處),那是馬上就會蹦出來報
告的。如果在“合法區”小範圍的越界,就沒有那麼敏感了,往往是程式一點反應都沒有,但實際上程式的運行結果已
經不符合設計初衷了。在沒有boundschecker的協助下,要怎麼樣找出這樣的問題呢。pageheap就是這樣一個工具軟體,
它針對Exe檔案而不是原始碼來尋找記憶體越界錯誤。在沒有原始碼或者你所用的IDE沒有boundschecker之類外掛程式的情況下,
用pageheap是一個非常好的選擇。首先,我們在微軟的網站上下載pageheap.exe。然後我們進入命令列狀態,假定
pageheap.exe 放在C盤,你的應用程式叫 myapp.exe 那麼進入C盤後,你可以輸入如下命令:
pageheap.exe /enable myapp.exe 斷行符號。
然後輸入 pageheap 斷行符號,查看是否已經開啟了對 myapp.exe 的監控。注意,pageheap是按照exe名來識別是否需要監控
的,而不是根據路徑,所以不能指定路徑。一旦指定exe名之後,無論在哪個路徑下,只要叫做myapp.exe的程式都會納入
監控範圍。當然,這種巧合是很少的,一般不會把別的程式也給監控了。想要取消對這個程式的監控,請用
“pageheap.exe /disable 應用程式名稱” 命令即可。
接下來再運行你的程式,你就會發現,事情發生了一些變化。
比如如下代碼,對堆記憶體的訪問明顯越界了:
/*
* WxButton4Click
*/
void Project1Dlg::WxButton4Click(wxCommandEvent& event)
{
// insert your code here
char * p=new char[5];
p[-1]=0;
delete[] p;
}
開啟pageheap監控和沒開啟時完全不一樣。開啟了監控的情況下,一旦執行這段,就馬上會報錯,協助你發現問題。
如果不開監控,執行這段會沒有反應,這掩蓋了問題,不是個好現象,會使運行結果出錯、在特殊條件下崩潰發作。
pageheap無法對已經啟動並執行程式切換監控狀態,所以每次開啟/停止對某個程式的監控後,需要重新啟動程式,才會生效。
pageheap無法對堆棧中的記憶體實施監控。
pageheap的原理是,當有堆分配的時候,在分配的記憶體的後面放上幾個守護位元組(Guard Bytes),
再跟上一個標記為PAGE_NOACCESS的記憶體頁。 這樣的話,一旦有越界的訪問,就會觸動這些PAGE_NOACCESS的記憶體,
windows自然就會報告了。那麼這些守護位元組到底有多少位元組呢,如果直接跨過了這些守護位元組去訪問記憶體空間
(比如上述代碼中,改為:p[100]=0),會不會就使得監控不起作用了呢?這種想法是對的,如果直接跨過了守護位元組,
確實監控不到。當然了,一般認為,大部分越界是順序訪問的,比如一個for迴圈中,總是會碰到守護位元組的,
所以出現直接繞過了守護位元組的情況很少。
該方法不但適用於wxDev-C++開發的程式,對VC++程式同樣適用,只是由於有boundschecker,所以用pageheap的必要性不
太大,在沒有原始碼的場合倒是可以發揮很大的作用。