共用方式為


死結偵測

死結偵測會監視驅動程式使用需要鎖定的資源 -- 微調鎖定、Mutex 和快速 Mutex。 此驅動程式驗證器選項會偵測可能在未來某個時間點造成死結的程式碼邏輯。

驅動程式驗證器的死結偵測選項以及 !deadlock 核心偵錯工具擴充功能是一個有效的工具,可確保您的程式碼避免使用這些資源不佳。

只有在 Windows XP 和更新版本的 Windows 中才支援死結偵測。

死結的原因

當兩個或多個執行緒對某些資源發生衝突時,就會造成 死結 ,因此無法執行。

最常見的死結形式是在兩個或多個執行緒等候另一個執行緒所擁有的資源時發生。 這如下所示:

執行緒 1 執行緒 2
擷取鎖定 A 擷取鎖定 B
要求鎖定 B 要求鎖定 A

如果這兩個序列同時發生,執行緒 1 永遠不會取得鎖定 B,因為執行緒 2 擁有,執行緒 2 永遠不會取得鎖定 A,因為執行緒 1 擁有。 此時,這會導致涉及的執行緒停止,而最糟的情況是讓系統停止回應。

死結不限於兩個執行緒和兩個資源。 三個執行緒與三個鎖定之間的三向死結很常見,甚至偶爾會發生五部分或六部分死結。 這些死結需要某種程度的「不良」,因為它們依賴同時發生的一些事。 不過,鎖定擷取的距離越遠,越有可能變成。

當執行緒嘗試擷取已經擁有的鎖定時,可能會發生單一線程死結。

所有死結之間的通用分母是未遵守鎖定階層。 每當需要一次取得多個鎖定時,每個鎖定都應該具有清楚的優先順序。 如果在 B 之前取得 A,而 B 在另一個點之前為 B,則階層是 A-B-C。 這表示 A 不得在 B 或 C 之後取得,且 B 不得在 C 之後取得。

即使沒有死結的可能性,仍應該遵循鎖定階層,因為在維護程式碼的過程中,意外導入死結會很容易。

可能導致死結的資源

最明確的死結是 擁有 資源的結果。 其中包括微調鎖定、Mutex、快速 Mutex 和 ERESOURCEs。

發出訊號而非取得的資源 (,例如事件和 LPC 埠,) 通常會造成更模棱兩可的死結。 當然,程式碼可能會誤用這些資源,因此兩個執行緒最終會無限期地等候完成,讓程式碼誤用這些資源。 不過,由於這些資源實際上不是由任何一個執行緒所擁有,因此無法以任何確定性來識別無條件執行緒。

驅動程式驗證程式的死結偵測選項會尋找涉及微調鎖定、Mutex 和快速 Mutex 的潛在死結。 它不會監視 ERESOURCEs 的使用,也不會監視非擁有資源的使用。

死結偵測的效果

驅動程式驗證器的死結偵測常式會尋找不一定同時發生的鎖定階層違規。 大部分情況下,這些違規會識別在有機率時將死結的程式碼路徑。

若要尋找潛在的死結,驅動程式驗證器會建置資源取得順序的圖表,並檢查迴圈。 如果您要為每個資源建立節點,並在每次取得一個鎖定之前繪製箭號,則路徑迴圈代表鎖定階層違規。

驅動程式驗證程式會在探索到其中一個違規時發出錯誤檢查。 這會在發生任何實際的死結之前發生。

注意

即使衝突的程式碼路徑永遠無法同時發生,如果它們牽涉到鎖定階層違規,仍應該重新撰寫這些路徑。 這類程式碼是「等候發生死結」,如果程式碼稍微重寫,可能會導致真正的死結。

當死結偵測發現違規時,它會發出錯誤檢查0xC4。 這個錯誤檢查的第一個參數會指出確切違規。 可能的違規包括:

  • 涉及鎖定階層違規的兩個或多個執行緒

  • 嘗試獨佔取得資源的執行緒,其已經是共用擁有者, (可以共用擁有的資源;共用資源無法獨佔取得) 。

  • 嘗試取得相同資源的執行緒, (自我死結) 兩次

  • 未先取得的資源

  • 由不同執行緒發行的資源,與取得它的資源不同

  • 已多次初始化或完全未初始化的資源

  • 在仍擁有資源時刪除的執行緒

  • 從 Windows 7 開始,驅動程式驗證器可以預測可能的死結。 例如,嘗試使用與一般微調鎖定和堆疊佇列微調鎖定相同的KSPIN_LOCK資料結構。

如需錯誤檢查參數的清單,請參閱 錯誤檢查0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) 。

監視死結偵測

一旦死結偵測發現違規, !deadlock 核心偵錯工具擴充功能就可以用來調查所發生的確切情況。 它可以顯示鎖定階層拓撲,以及最初取得鎖定時每個執行緒的呼叫堆疊。

!deadlock擴充功能的詳細範例,以及偵錯工具延伸模組的一般資訊,請參閱 Windows 套件的偵錯工具檔中。 如需詳細資訊,請參閱 Windows 偵錯

啟用此選項

注意

此選項與核心同步處理延遲模糊不相容

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

  • 在命令列

    在命令列中,[死結偵測] 選項是由 位 5 (0x20) 表示。 若要啟用死結偵測,請使用旗標值0x20或將0x20新增至旗標值。 例如:

    verifier /flags 0x20 /driver MyDriver.sys
    

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

    在 Windows Vista 和更新版本的 Windows 上,您也可以藉由將 /volatile 參數新增至 命令,來啟用和停用死結偵測,而不需要重新開機電腦。 例如:

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

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

    死結偵測功能也會包含在標準設定中。 例如:

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

    1. 選取 [為程式碼開發人員建立自訂設定 () ],然後選取 [ 下一步]。

    2. 從完整清單中選取 [選取個別設定]。

    3. 選取 [ (檢查) 死結偵測

死結偵測功能也會包含在標準設定中。 若要使用這項功能,請在 [驅動程式驗證器管理員] 中,選取 [ 建立標準設定]。