共用方式為


診斷 Managed 偵錯助理的錯誤

Managed 偵錯助理 (MDA) 是搭配 Common Language Runtime (CLR) 一起使用的偵錯輔助工具,藉以提供執行階段狀態的資訊。 此偵錯助理會產生無法以其他方式截獲的執行階段事件之相關資訊性訊息。 您可使用 MDA 來隔離在 Managed 和 Unmanaged 程式碼之間轉換時所發生,但很難找到的應用程式錯誤。 您可以在 Windows 登錄內加入機碼,或設定環境變數,藉以啟用或停用所有的 MDA。 您可以使用應用程式組態設定來啟用特定的 MDA。 您可以針對應用程式組態檔中的某些個別 MDA 設定其他組態設定; 因為載入執行階段時會剖析這些組態檔,所以您必須先啟用 MDA 之後,再啟動 Managed 應用程式。 如果是已經啟動的應用程式,就無法啟用 MDA。

注意事項注意事項

啟用 MDA 時,即使您的程式碼不是在偵錯工具下執行,MDA 仍為作用中。如果引發 MDA 事件時偵錯工具不存在,則事件訊息會顯示在未處理的例外狀況對話方塊中 (雖然這不是未處理的例外狀況)。如果要避免顯示這個對話方塊,請於程式碼不在偵測環境下執行時,移除會啟用 MDA 的設定。

注意事項注意事項

當您的程式碼在 Visual Studio 整合式開發環境 (IDE) 中執行時,可以避免出現特定 MDA 事件發生時所顯示的例外狀況對話方塊。若要這麼做,請按一下 [偵錯] 功能表上的 [例外狀況] (如果 [偵錯] 功能表未包含 [例外狀況] 命令,請按一下 [工具] 功能表上的 [自訂] 新增該命令)。在 [例外狀況] 對話方塊中,展開 [Managed 偵錯助理] 清單,然後清除個別 MDA 的 [擲回] 核取方塊。例如,若要避免 contextSwitchDeadlock MDA 的例外狀況對話方塊,請在 [Managed 偵錯助理] 清單中,清除其名稱旁邊的 [擲回] 核取方塊。您也可以用此對話方塊來啟用 MDA。

下表將列出隨附於 .NET Framework 中的 MDA。

asynchronousThreadAbort MDA

bindingFailure MDA

callbackOnCollectedDelegate MDA

contextSwitchDeadlock MDA

dangerousThreadingAPI MDA

dateTimeInvalidLocalFormat MDA

dirtyCastAndCallOnInterface MDA

disconnectedContext MDA

dllMainReturnsFalse MDA

exceptionSwallowedOnCallFromCom MDA

failedQI MDA

fatalExecutionEngineError MDA

gcManagedToUnmanaged MDA

gcUnmanagedToManaged MDA

illegalPrepareConstrainedRegion MDA

invalidApartmentStateChange MDA

invalidCERCall MDA

invalidFunctionPointerInDelegate MDA

invalidGCHandleCookie MDA

invalidIUnknown MDA

invalidMemberDeclaration MDA

invalidOverlappedToPinvoke MDA

invalidVariant MDA

jitCompilationStart MDA

loaderLock MDA

loadFromContext MDA

marshalCleanupError MDA

封送處理 MDA

memberInfoCacheCreation MDA

moduloObjectHashcode MDA

nonComVisibleBaseClass MDA

notMarshalable MDA

openGenericCERCall MDA

overlappedFreeError MDA

pInvokeLog MDA

pInvokeStackImbalance MDA

raceOnRCWCleanup MDA

重新進入 MDA

releaseHandleFailed MDA

reportAvOnComRelease MDA

streamWriterBufferedDataLost MDA

virtualCERCall MDA

根據預設,.NET Framework 會啟動所有 Managed 偵錯工具的 MDA 之子集。 您可以按一下 [偵錯] 功能表中的 [例外狀況] 並展開 [Managed 偵錯助理] 清單,以檢視 Visual Studio 中的預設設定。

啟用及停用 MDA

您可以使用登錄機碼、環境變數和應用程式組態設定來啟用及停用 MDA。 您必須啟用登錄機碼或環境變數,才能使用應用程式組態設定。

在 Visual Studio 2005 及稍後的版本中,當裝載處理序啟用時,您就不能停用預設設定中的 MDA,或是啟用不在預設設定中的 MDA。 預設為啟用裝載處理序,所以必須明確停用。

如果要停用 Visual Studio 中的裝載處理序,請執行下列步驟:

  1. 在 [方案總管] 中選取專案。

  2. 按一下 [專案] 功能表上的 [屬性]。

    [專案設計工具] 視窗隨即出現。

  3. 按一下 [偵錯] 索引標籤。

  4. 在 [啟用偵錯工具] 區段中,清除 [啟用 Visual Studio 裝載處理序] 核取方塊。

但是,停用裝載處理序會影響效能。 您可以在收到 MDA 通知時避免 Visual Studio 顯示 MDA 對話方塊,以避免停用 MDA。 如果要這麼做,請按一下 [偵錯] 功能表上的 [例外狀況],展開 [Managed 偵錯助理] 清單,然後選取或清除個別 MDA 的 [擲回] 核取方塊。

使用登錄機碼啟用及停用 MDA

您可以在 Windows 登錄中加入 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\MDA 子機碼 (型別 REG_SZ,值 1) 來啟用 MDA。 若要在另一台電腦上啟用 MDA,請將下列範例複製到名為 "MDAEnable.reg" 的文字檔中,並在 [Windows 檔案總管] 中按兩下檔名。

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"MDA"="1"

若要停用 MDA,請使用 Windows 登錄編輯程式將 MDA 子機碼設為 0 (零)。 或者,將下列範例複製到名為 "MDADisable.reg" 的文字檔中,並在 [Windows 檔案總管] 中按兩下檔名。

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"MDA"="0"

根據預設,當執行附加到偵錯工具的應用程式時,會啟用某些 MDA,即使是未加入登錄機碼也一樣。 這類助理工具的範例有 pInvokeStackImbalance MDAinvalidApartmentStateChange MDA; 您可以依照前面所述的步驟來執行 MDADisable.reg 檔,以停用這些助理工具。

使用環境變數啟用及停用 MDA

環境變數 COMPLUS_MDA 也可以控制 MDA 的啟動,此環境變數會覆寫登錄機碼。 COMPLUS_MDA 字串是不區分大小寫、以分號區隔的 MDA 名稱或其他特殊控制字串的清單。 在 Managed 或 Unmanaged 偵錯工具之下啟動時,預設會啟用一組 MDA。 其執行方式是以隱含方式將預設在偵錯工具之下啟用之以分號分隔的 MDA 清單,附加到環境變數或登錄機碼值的前面。 特殊控制字串如下所示:

  • 0 - 停用所有 MDA。

  • 1 - 從 ApplicationName.mda.config 讀取 MDA 設定。

  • managedDebugger - 在偵錯工具之下啟動 Managed 可執行檔時,明確啟動所有隱含啟動的 MDA。

  • unmanagedDebugger - 在偵錯工具之下啟動 Unmanaged 可執行檔時,明確啟動所有隱含啟動的 MDA。

如果有衝突的設定,最近的設定會覆寫之前的設定:

  • COMPLUS_MDA=0 會停用所有 MDA,包括在偵錯工具之下隱含啟用的 MDA。

  • COMPLUS_MDA=gcUnmanagedToManaged 會啟用 gcUnmanagedToManaged,以及在偵錯工具之下任何隱含啟用的 MDA。

  • COMPLUS_MDA=0;gcUnmanagedToManaged 會啟用 gcUnmanagedToManaged,但是會停用其他情況下在偵錯工具之下隱含啟用的 MDA。

使用應用程式特定的組態設定啟用及停用 MDA

您可以在應用程式的 MDA 組態檔中,個別啟用、停用及設定某些助理工具。 若要啟用應用程式組態檔來設定 MDA,必須設定 MDA 登錄機碼或 COMPLUS_MDA 環境變數。 應用程式組態檔通常位於應用程式可執行檔 (.exe) 所在的目錄中。 此檔名的格式為 ApplicationName.mda.config,例如 notepad.exe.mda.config。 在此應用程式組態檔中啟用的助理工具可能具有專門設計用來控制該助理工具行為的屬性或項目。 下列範例將示範如何啟用及設定封送處理 MDA

<mdaConfig>
  <assistants>
    <marshaling>
      <methodFilter>
        <match name="*"/>
      </methodFilter>
      <fieldFilter>
        <match name="*"/>
      </fieldFilter>
    </marshaling>
  </assistants>
</mdaConfig>

Marshaling MDA 會發出資訊,以描述針對應用程式中每一個 Managed 到 Unmanaged 轉換而封送處理為 Unmanaged 型別的 Managed 型別。 Marshaling MDA 还可以分別篩選 <methodFilter> 和 <fieldFilter> 子項目中提供之方法和結構欄位的名稱。

下列範例顯示如何使用其預設值啟用多個 MDA。

<mdaConfig>
  <assistants>
    <illegalPrepareConstrainedRegion />
    <invalidCERCall />
    <openGenericCERCall />
    <virtualCERCall />
  </assistants>
</mdaConfig>
重要事項重要事項

當您在組態檔中指定多個助理時,必須以字母順序列出。例如,如果您要啟動 virtualCERCall 和 invalidCERCall MDA,則必須在加入 <virtualCERCall /> 項目前,加入 <invalidCERCall /> 項目。如果未以字母順序列出這些項目,則會顯示未處理的不正確組態檔例外狀況訊息。

MDA 輸出

MDA 輸出與下列範例類似,範例中將顯示 pInvokeStackImbalance MDA 的輸出。

A call to PInvoke function 'MDATest!MDATest.Program::StdCall' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

請參閱

其他資源

偵錯、追蹤和程式碼剖析