共用方式為


驅動程式驗證器中的特殊集區記憶體損毀偵測

記憶體損毀是常見的驅動程式問題。 驅動程式錯誤可能會導致在錯誤發生後很長一段時間內當機。 這些錯誤中最常見的是存取已釋放的記憶體,並分配 n 個位元組,然後存取 n+1 個位元組。

若要偵測記憶體損毀,驅動程式驗證器可以從特殊集區配置驅動程式記憶體,並監視該集區是否有不正確的存取。 會針對核心模式系統提供的常式 (例如 ExAllocatePoolWithTag ) 和 GDI 系統提供的常式 (例如 EngAllocMem) 提供特殊集區支援。

按定線劃分的特殊池

特殊池有兩種排版可供選擇:

  • 驗證開始」對齊方式更適合偵測存取不足情況。
  • 驗證結束 」對齊方式更適合偵測存取溢出。

如需如何使用「 驗證開始」 和「 驗證結束 」選項的詳細資訊,請參閱 偵測溢出和欠支。 請注意,絕大多數記憶體損毀是由於 溢出,而不是不足。

當「特殊儲存區」特性處於作用中狀態,且已選取「 驗證結束」 時,驅動程式所要求的每一個記憶體配置都會放在個別頁面上。 會傳回允許配置適合頁面的最高可能位址,以便記憶體與頁面結尾對齊。 頁面的前一部分是用特殊圖案寫的。 上一頁和下一頁被標記為無法訪問。

如果驅動程式在配置結束之後嘗試存取記憶體,驅動程式驗證器會立即偵測到此情況,並發出 錯誤檢查0xCD。 如果驅動程式在緩衝區開始之前寫入記憶體,這可能會 (大概) 變更模式。 釋放緩衝區時,驅動程式驗證器會偵測變更,並發出 錯誤檢查0xC1

如果驅動程式在釋放緩衝區之後讀取或寫入緩衝區,驅動程式驗證器會發出 錯誤檢查0xCC

選取 [驗證開始] 時,記憶體緩衝區會與頁面的開頭對齊。 使用此設定時,不足會導致立即進行錯誤檢查,而超限在釋放記憶體時會造成錯誤檢查。 此選項在其他方面與 驗證結束 選項相同。

確認結束是預設的對齊方式,因為在驅動程式中,過載錯誤比不足錯誤更常見。

個別記憶體配置可以覆寫這些設定,並藉由呼叫 ExAllocatePoolWithTagPriority ,並將 Priority 參數設定為 XxxSpecialPoolOverrun 或 XxxSpecialPoolUnderrun,來選擇其對齊方式。 (此常式無法啟用或停用特殊儲存區特性,或要求特殊儲存區進行記憶體配置,否則會從一般儲存區配置。只能從此常式控制坐標系。

在 Windows 7 和更新版本的 Windows 作業系統中,特殊集區選項支援使用下列核心 API 配置的記憶體:

依據集區標籤或配置大小的特殊集區

除了驅動程式驗證器的特殊集區功能 (要求指定 驅動程式配置的特殊集區) 之外,還有另外兩種方式可以使用特殊集區:

  • 集區標籤。 要求具有指定集區標籤的所有配置的特殊集區。

  • 大小。 要求指定大小範圍內所有配置的特殊集區。

若要針對集區標籤或大小範圍請求特殊集區,請使用 Gflags,它是包含在Windows 偵錯工具中的一項工具。 如需詳細資訊,請參閱 使用全域旗標公用程式

您可以同時使用驅動程式驗證器的特殊集區功能,以及 Gflags 的特殊集區功能。 如果您這樣做,請記住特殊集區的資源是有限的,並非所有從特殊集區配置的嘗試都會成功,而且即使嘗試失敗,若是從一般記憶體集區的配置滿足了這些需求,Windows 也會傳回成功狀態。

特殊泳池效率

並非所有特殊泳池要求都能得到滿足。 特殊存放區的每一次分配會使用一頁非分頁的物理內存和兩頁虛擬地址空間。 如果儲存區已用盡,則會以標準方式配置記憶體,直到特殊儲存區再次可用為止。 當從標準集區填入特殊集區要求時,要求函式不會傳回錯誤,因為集區要求已成功。 因此,如果啟動了特殊池功能,則不建議同時驗證多個驅動程式。

提出許多小型記憶體要求的單一驅動程式也可以耗盡此集區。 如果發生這種情況,最好將集區標籤指派給驅動程式的記憶體配置,並將特殊集區一次專用給一個集區標籤。

特殊儲存區的大小會隨著系統上的實體記憶體數量而增加;理想情況下,這應該至少是 1 GB (GB)。 在 x86 機器上,因為會耗用虛擬 (除了實體) 空間,因此請勿使用 /3GB 開機選項。 將頁面檔案的最小/最大數量增加兩到三倍也是一個好主意。

為確保駕駛員的所有分配都經過測試,建議長時間給駕駛員施加壓力。

監視特殊集區

可以監控與集區分配相關的統計資料。 這些可以由驅動程式驗證器管理員、Verifier.exe 命令列或記錄檔顯示。 如需詳細資訊 ,請參閱監視全域計數器

如果 [集區配置成功於特殊集區] 計數器等於 [集區配置成功 ] 計數器,則特殊集區已足以涵蓋所有記憶體配置。 如果前一個計數器低於後者,則特殊資源池至少在某個時候已被耗盡一次。

這些計數器不會追蹤一頁或更大大小的配置,因為特殊集區不適用於它們。

如果已啟用特殊集區功能,但從特殊集區指派的所有集區配置少於 95%,則驅動程式驗證器管理員中會出現警告。 在 Windows 2000 中,此警告會出現在 [驅動程序狀態 ] 畫面上。 在 Windows XP 和更新版本中,此警告將出現在 [全域計數器 ] 畫面上。 如果發生這種情況,您應該驗證較短的驅動程式清單、依集區標籤驗證個別集區,或將更多實體記憶體新增至系統。

核心偵錯工具延伸模組 !verifier 也可用來監視特殊集區使用情況。 它會顯示與驅動程式驗證器管理員類似的資訊。 如需調試程式擴充功能的相關信息,請參閱 Windows 偵錯

啟動特殊集區選項

您可以使用驅動程式驗證器管理員或 Verifier.exe 命令列,啟用一或多個驅動程式的特殊集區功能。 如需詳細資訊,請參閱 選取驅動程式驗證器選項

備註

若要依儲存區標籤或配置大小來啟動「特殊儲存區」特性,或設定 「驗證開始 」(偵測欠載)及 「驗證結束 」(偵測溢出)對齊方式,請使用 「廣域旗標」公用程式;這些坐標系設定會套用至所有特殊集區配置。

  • 在命令行

    在命令列中,特殊池選項由 位元0(0x1)表示。 若要啟動特殊集區,請使用旗標值 0x1 或將0x1新增至旗標值。 例如:

    verifier /flags 0x1 /driver MyDriver.sys
    

    下一次開機之後,此功能將會處於作用中狀態。

    您也可以透過在命令中新增 /volatile 參數來啟動和停用特殊池,而無需重新啟動電腦。 例如:

    verifier /volatile /flags 0x1 /adddriver MyDriver.sys
    

    此設定會立即生效,但會在您關閉或重新啟動電腦時遺失。 如需詳細資訊,請參閱 使用動態設定

    特殊池功能也包含在標準設置中。 例如:

    verifier /standard /driver MyDriver.sys
    
  • 使用驅動程式驗證器管理員

    1. 選取 [建立自定義設定] (適用於程式代碼開發人員), 然後按 [ 下一步]。
    2. 選擇 從完整清單中選取個別設定
    3. 選擇(勾選) 特殊池

    特殊池功能也包含在標準設置中。 若要使用此功能,請在 [驅動程序驗證器管理員] 中,按兩下 [建立標準設定]。