Diagnostizieren von Fehlern mit Assistenten für verwaltetes Debuggen

MDAs sind Hilfsmittel, die mit der Common Language Runtime (CLR) zusammenarbeiten, um Informationen zum Laufzeitzustand bereitzustellen. Die Assistenten generieren Informationsmeldungen über Laufzeitereignisse, die Sie auf keine andere Art abfangen können. Sie können MDAs verwenden, um schwer aufzufindende Anwendungsfehler zu isolieren, die bei Übergängen zwischen verwaltetem und nicht verwaltetem Code auftreten.

Alle MDAs können durch Hinzufügen eines Schlüssels zur Windows-Registrierung oder durch Festlegen einer Umgebungsvariable aktiviert oder deaktiviert werden. Sie können bestimmte MDAs mithilfe von Anwendungskonfigurationseinstellungen aktivieren. In der Konfigurationsdatei der Anwendung können Sie zusätzliche Konfigurationseinstellungen für einige der MDAs festlegen. Da die Konfigurationsdateien beim Laden der Laufzeit analysiert werden, müssen Sie den MDA bereitstellen, bevor die verwaltete Anwendung gestartet wird. Sie können ihn nicht für Anwendungen bereitstellen, die bereits gestartet wurden.

In der folgenden Tabelle werden die MDAs im Lieferumfang von .NET Framework aufgeführt:

MDA
asynchronousThreadAbort
bindingFailure
callbackOnCollectedDelegate
contextSwitchDeadlock
dangerousThreadingAPI
dateTimeInvalidLocalFormat
dirtyCastAndCallOnInterface
disconnectedContext
dllMainReturnsFalse
exceptionSwallowedOnCallFromCom
failedQI
fatalExecutionEngineError
gcManagedToUnmanaged
gcUnmanagedToManaged
illegalPrepareConstrainedRegion
invalidApartmentStateChange
invalidCERCall
invalidFunctionPointerInDelegate
invalidGCHandleCookie
invalidIUnknown
invalidMemberDeclaration
invalidOverlappedToPinvoke
invalidVariant
jitCompilationStart
loaderLock
loadFromContext
marshalCleanupError
marshaling
memberInfoCacheCreation
moduloObjectHashcode
nonComVisibleBaseClass
notMarshalable
openGenericCERCall
overlappedFreeError
pInvokeLog
pInvokeStackImbalance
raceOnRCWCleanup
reentrancy
releaseHandleFailed
reportAvOnComRelease
streamWriterBufferedDataLost
virtualCERCall

Standardmäßig aktiviert .NET Framework eine Teilmenge von MDAs für alle verwalteten Debugger. Sie können den Standardsatz in Visual Studio anzeigen, indem Sie im Menü Debuggen auf Windows>Ausnahmeeinstellungen klicken und dann die Liste Assistenten für verwaltetes Debuggen erweitern.

Exception Settings window in Visual Studio

Aktivieren und Deaktivieren von MDAs

Sie können MDAs mit einem Registrierungsschlüssel, einer Umgebungsvariablen und Anwendungskonfigurationseinstellungen bereitstellen sowie deren Bereitstellung aufheben. Sie müssen entweder den Registrierungsschlüssel oder die Umgebungsvariable für die Verwendung der Anwendungskonfigurationseinstellungen aktivieren.

Tipp

Anstatt MDAs zu deaktivieren, können Sie verhindern, dass Visual Studio beim Empfang einer MDA-Benachrichtigung das MDA-Dialogfeld anzeigt. Klicken Sie hierzu im Menü Debuggen auf Windows>Ausnahmeeinstellungen, erweitern Sie die Liste Assistenten für verwaltetes Debuggen, und aktivieren bzw. deaktivieren Sie das Kontrollkästchen Bei Auslösung anhalten für den jeweiligen MDA.

Registrierungsschlüssel

Sie können MDAs bereitstellen, indem Sie der Windows-Registrierung den Unterschlüssel HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\MDA (Typ: REG_SZ, Wert: 1) hinzufügen. Kopieren Sie das folgende Beispiel in eine Textdatei mit dem Namen MDAEnable.reg. Öffnen Sie den Windows-Registrierungs-Editor (RegEdit.exe), und wählen Sie im Menü Datei den Eintrag Importieren aus. Wählen Sie die Datei MDAEnable.reg aus, um auf diesem Computer MDAs zu aktivieren. Durch Festlegen des Unterschlüssels auf den Zeichenfolgenwert 1 (nicht den DWORD-Wert 1) wird das Lesen der MDA-Einstellungen aus der Datei „ApplicationName.suffix.mda.config“ aktiviert. Die MDA-Konfigurationsdatei für Editor würde beispielsweise den Namen „notepad.exe.mda.config“ erhalten.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"MDA"="1"

Führt der Computer eine 32-Bit-Anwendung auf einem 64-Bit-System aus, dann sollte der MDA-Schlüssel folgendermaßen festgelegt sein:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
"MDA"="1"

Weitere Informationen finden Sie unter Anwendungsspezifische Konfigurationseinstellungen. Die Registrierungseinstellung kann durch die Umgebungsvariable COMPLUS_MDA überschrieben werden. Weitere Informationen finden Sie unter Umgebungsvariable.

Zum Deaktivieren von MDAs legen Sie den Unterschlüssel „MDA“ über den Windows-Registrierungs-Editor auf 0 (Null) fest.

In der Standardeinstellung werden einige MDAs bereitgestellt, wenn Sie eine Anwendung ausführen, die an einen Debugger angehängt ist. Dies gilt auch, wenn der Registrierungsschlüssel nicht hinzugefügt wurde. Sie können diese Assistenten deaktivieren, indem Sie die Datei MDADisable.reg wie weiter oben in diesem Abschnitt beschrieben ausführen.

Umgebungsvariable

Sie können die MDA-Aktivierung auch mithilfe der Umgebungsvariablen COMPLUS_MDA steuern, die den Registrierungsschlüssel überschreibt. Die Zeichenfolge COMPLUS_MDA ist eine durch Semikolon getrennte Liste von MDA-Namen und anderen Steuerzeichenfolgen, bei der die Groß-/Kleinschreibung nicht beachtet wird. Bei einem Start unter einem verwalteten oder nicht verwalteten Debugger wird standardmäßig ein Satz MDAs bereitgestellt. Dies wird erzielt, indem die durch Semikolons getrennte Liste der MDAs, die standardmäßig unter Debuggern bereitgestellt werden, dem Wert der Umgebungsvariablen oder des Registrierungsschlüssels vorangestellt wird. Folgende Steuerzeichenfolgen sind verfügbar:

  • 0: Deaktiviert alle MDAs.

  • 1: Liest MDA-Einstellungen aus ApplicationName.mda.config.

  • managedDebugger: Aktiviert ausdrücklich alle MDAs, die implizit aktiviert werden, wenn eine verwaltete ausführbare Datei unter einem Debugger gestartet wird.

  • unmanagedDebugger: Aktiviert ausdrücklich alle MDAs, die implizit aktiviert werden, wenn eine nicht verwaltete ausführbare Datei unter einem Debugger gestartet wird.

Wenn widersprüchliche Einstellungen vorhanden sind, überschreiben die neueren Einstellungen die älteren Einstellungen:

  • COMPLUS_MDA=0: Deaktiviert alle MDAs einschließlich der MDAs, die implizit unter einem Debugger aktiviert werden.

  • COMPLUS_MDA=gcUnmanagedToManaged stellt gcUnmanagedToManaged zusätzlich zu allen MDAs bereit, die unter einem Debugger implizit aktiviert werden.

  • COMPLUS_MDA=0;gcUnmanagedToManaged aktiviert gcUnmanagedToManaged, aber deaktiviert die MDAs, die andernfalls implizit unter einem Debugger aktiviert werden.

Anwendungsspezifische Konfigurationseinstellungen

In der MDA-Konfigurationsdatei für die Anwendung können Sie einige MDAs einzeln bereitstellen und konfigurieren bzw. deren Bereitstellung aufheben. Damit MDAs mithilfe einer Anwendungskonfigurationsdatei konfiguriert werden können, muss entweder der MDA-Registrierungsschlüssel oder die Umgebungsvariable COMPLUS_MDA festgelegt sein. Die Anwendungskonfigurationsdatei befindet sich i. d. R. im selben Verzeichnis wie die ausführbare Datei (.exe) der Anwendung. Der Dateiname weist das Format „Anwendungsname.mda.config“ auf, z. B. „notepad.exe.mda.config“. Assistenten, die in der Anwendungskonfigurationsdatei aktiviert sind, können Attribute oder Elemente enthalten, die das Verhalten des jeweiligen Assistenten steuern.

Das folgende Beispiel zeigt, wie Sie das Marshalling aktivieren und konfigurieren:

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

Der Marshaling-MDA gibt für jeden Übergang von verwalteten zu nicht verwalteten Typen in der Anwendung Informationen über den verwalteten Typ aus, der per Marshalling von einem verwalteten in einen nicht verwalteten Typ umgewandelt wird. Der Marshaling-MDA kann außerdem die Namen der Methoden- und Strukturfelder filtern, die in den untergeordneten Elementen methodFilter bzw. fieldFilter angegeben sind.

Das folgende Beispiel zeigt, wie Sie mehrere MDAs unter Verwendung ihrer Standardeinstellungen aktivieren:

<mdaConfig>
  <assistants>
    <illegalPrepareConstrainedRegion />
    <invalidCERCall />
    <openGenericCERCall />
    <virtualCERCall />
  </assistants>
</mdaConfig>

Wichtig

Wenn Sie in einer Konfigurationsdatei mehr als einen Assistenten angeben, müssen Sie diese in alphabetischer Reihenfolge aufführen. Wenn Sie z. B. sowohl den virtualCERCall-MDA als auch den invalidCERCall-MDA bereitstellen möchten, müssen Sie den <invalidCERCall />-Eintrag vor dem <virtualCERCall />-Eintrag hinzufügen. Falls die Einträge nicht in alphabetischer Reihenfolge aufgeführt sind, wird eine Meldung mit einer unbehandelten Ausnahme zu einer ungültigen Konfigurationsdatei angezeigt.

MDA-Ausnahmen

Wenn ein MDA aktiviert wurde, ist er auch dann aktiv, wenn Ihr Code nicht über einen Debugger ausgeführt wird. Wenn ein MDA-Ereignis ausgelöst wird, wenn kein Debugger vorhanden ist, wird die Ereignismeldung in einem Dialogfeld für unbehandelte Ausnahmen angezeigt, obwohl dies keine unbehandelte Ausnahme darstellt. Um das Anzeigen dieses Dialogfelds zu vermeiden, entfernen Sie die Einstellungen zur Aktivierung des MDA, wenn der Code nicht in einer Debugumgebung ausgeführt wird.

Wenn Ihr Code in der integrierten Entwicklungsumgebung (IDE) von Visual Studio ausgeführt wird, können Sie das für bestimmte MDA-Ereignisse angezeigte Ausnahmedialogfeld umgehen. Wählen Sie dazu im Menü Debuggen die Option Windows>Ausnahmeeinstellungen aus. Erweitern Sie im Fenster Ausnahmeeinstellungen die Liste Assistenten für verwaltetes Debuggen, und deaktivieren Sie das Kontrollkästchen Bei Auslösung anhalten für den jeweiligen MDA. Sie können dieses Dialogfeld auch verwenden, um die Anzeige von MDA-Ausnahmedialogfeldern zu aktivieren.

MDA-Ausgabe

Die MDA-Ausgabe ähnelt dem folgenden Beispiel, das die Ausgabe von MDA PInvokeStackImbalance zeigt:

Ein Aufruf der PInvoke-Funktion „MDATest!MDATest.Program::StdCall“ hat zu einem Ungleichgewicht im Stapel geführt. Dies liegt wahrscheinlich daran, dass die verwaltete PInvoke-Signatur nicht mit der der unverwalteten Zielsignatur übereinstimmt. Überprüfen Sie, ob die Aufrufkonvention und die Parameter der PInvoke-Signatur der nicht verwalteten Zielsignatur entsprechen.

Weitere Informationen