<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    使用PageHeap.EXE或GFlags.EXE檢查內存越界錯誤

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    必先利其器之一:使用PageHeap.EXE或GFlags.EXE檢查內存越界錯誤

    Article last modified on 2002-6-3

    ----------------------------------------------------------------

    The information in this article applies to:

    -        Microsoft Visual C++, 32-bit Editions, version 6.0, SP5

    ----------------------------------------------------------------

     

    我推薦使用PageHeap.Exe和Gflags.Exe,主要的原因還是因為當有人問內存越界的錯誤如何查出來的時候,國外的朋友經常會推薦這兩個工具(highly recommend)。我用過之后,也覺得有些時候用用還是有好處的。

     

    PageHeap.Exe將針對某個指定的應用程序啟用Page Heap標志,從而自動監視所有的malloc、new和heapAlloc的內存分配,找出內存錯誤。

    PageHeap.Exe的下載地點:

    http://support.microsoft.com/default.aspx?scid=http://download.microsoft.com/download/vc60pro/Utility/6.0/WIN98/EN-US/PageHeap1.exe

     

    下面我們簡單地給出PageHeap使用步驟:

    第一步:

    在命令行中運行PageHeap.Exe。如果你以前設置過啟用Global Page Heap標志,那么你將看到一個列表,給出所有已經啟用了的應用程序的名字,不含路徑。

    如下所示:

    C:/>pageheap

    pgh.exe                                  enabled

    testSplit.exe                            enabled

     

    第二步:

    編譯一個小程序,其中有如下代碼:

    void main()

    {

      int m_len = 5;

      char *m_p = (char *)HeapAlloc (GetProcessHeap (),   HEAP_ZERO_MEMORY, m_len);

      m_p[m_len] = 0;

     

      HeapFree (GetProcessHeap (),0, m_p);

    }

    Build出一個Debug版本。運行之,你看不到有任何異常的報告。

    但其實m_p[m_len]=0這句話就是越界寫了,因為只分配到了m_p[m_len-1]!這種情況就叫Dynamic memory overrun。用BoundsChecker是可以查到的。

    這時,表面上看不出任何問題,但是一顆定時炸彈已經埋下了。

     

    第三步:

    在命令行中運行PageHeap /enable YourApplicationName.exe 0x01

    再運行一次不帶參數的PageHeap,察看上面的命令是否生效。你的應用程序應該在啟用的列表中。

    注意:千萬不要在YourApplication.Exe前面加上路徑!!

    0x01的含義在后面說明。

     

    第四步:

    再次運行你的程序。

    你將會注意到在Output窗口的加載各種DLL之前,多了幾句話:

    Loaded exports for 'C:/WINNT/System32/ntdll.dll'

    Page heap: process 0x57C created heap @ 00130000 (00230000, flags 0x1)

    Loaded 'C:/WINNT/system32/MFC42D.DLL', no matching symbolic information found.

    ..

    Loaded 'C:/WINNT/system32/MSVCP60D.DLL', no matching symbolic information found.

    Page heap: process 0x57C created heap @ 00470000 (00570000, flags 0x1)

    Loaded exports for 'C:/WINNT/system32/imm32.dll'

    這就是Page Heap的監視機制在發揮作用!他告訴你你的堆00470000被創建出來了。

    然后程序退出后,Output窗口有這么幾句話表明一定有什么錯誤發生了:

    Page heap: block @ 0015AFF8 is corrupted (reason 10)

    Page heap: reason: corrupted suffix pattern

    Page heap: process 0x57C destroyed heap @ 00471000 (00570000)

    The thread 0x8A8 has exited with code 0 (0x0).

    這說明在銷毀堆00470000時遇到了麻煩,就是數據塊0015AFF8被誤用了,原因是誤用了下標語法。看,說得多么清楚!也節省了許多翻來覆去查代碼的工作!

     

    PageHeap的使用中有幾點值得注意:

    1:啟用PageHeap不能夠影響正在運行中的應用程序。如果你需要啟用一些正在運行且不能重啟的程序的PageHeap,那請運行PageHeap啟用后,重新啟動機器。

    2:要想查看PageHeap把信息放到哪里了,請打開你的注冊表,來到

       /HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT

    /CurrentVersion/Image File Execution Options

    你將會看到你的應用程序也在這個項下面。你的應用程序的GlobalFlag被設置為了0x02000000,PageHeapFlags被設置為了0x01。

    3:PageHeap的原理是這樣,它在已分配的內存的后面放上幾個守護字節(Guard Bytes),再跟上一個標記為PAGE_NOACCESS的內存頁。這樣,已分配內存的后面如果被重寫了,那么守護字節就會被改變,于是當內存被釋放時,PageHeap就會引發一個AV(Access Violation)。大體上就是這樣。所以只有最后釋放這塊問題內存時,才會有PageHeap的報告!這就是PageHeap的局限性吧。

    參數0x01的含義:

    FLAGS hex value (0x...) has the following structure:

     

        B7-B0   Bit flags    1 - enable page heap

     

             01 - enable page heap. If zero normal heap is used.

                  In 99% of the cases you will want this to be set.

             02 - collect stack traces (default on checked builds)

             04 - minimize memory impact

             08 - minimize randomly(1)/based on size range(0)

         10 - catch backward overruns

    看到了嗎?你還可以設置參數為0x10,從而可以檢查內存向前的越界寫!

    Gflags.Exe是微軟的Debugging Tools里面的工具。在Windows 2000的Resource Kit中也可以找得到。我們也可以用它來完成和PageHeap相同的任務。當然,Gflags.EXE還能做許許多多其他的事情。這里我們就不介紹了,總之物超所值。

    具體的使用辦法是:

    1)     運行Gflags.Exe;

    2)  你將看到一個對話框。在”Image File”的編輯框中寫下你的應用程序的名字,如YourApp.Exe。注意不要路徑!

    3)  選擇”Image File Options”的單選鈕;

    4)  這時,你會看到對話框的內容突然一變。選中“Place heap
    allocations at ends of pages”前的復選框。

    5)  點擊Apply按鈕。

    這樣,就達到了PageHeap的效果。現在運行你的程序,overwrite你的堆,就應該生成一個AV了!

     

    (預知詳情請收聽微軟KB:SAMPLE: PageHeap1.exe Finds Heap Corruption and Memory Errors (Q264471) 你可以按照這篇文檔所指引的步驟學習如何使用PageHeap)

     

     

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全