Vereinfachen des Debuggens eines Images

Beim Kompilieren von nicht verwaltetem Code können Sie durch das Festlegen von IDE-Schaltern oder Befehlszeilenoptionen ein ausführbares Abbild zum Debuggen konfigurieren. Sie können beispielsweise die Befehlszeilenoption /Zi in Visual C++ verwenden, um zur Ausgabe von Debugsymboldateien aufzufordern (Dateierweiterung „.pdb“). Dementsprechend weist die Befehlszeilenoption /Od den Compiler an, die Optimierung zu deaktivieren. Der resultierende Code wird langsamer ausgeführt, lässt sich jedoch gegebenenfalls einfacher debuggen.

Beim Kompilieren von in .NET Framework verwaltetem Code kompilieren Compiler wie Visual C++, Visual Basic und C# ihr Quellprogramm in die Common Intermediate Language (CIL). Das CIL-Ergebnis wird dann per Just-In-Time-Verfahren (JIT) direkt vor der Ausführung in nativen Computercode kompiliert. Ähnlich wie bei nicht verwaltetem Code können Sie durch das Festlegen von IDE-Schaltern oder Befehlszeilenoptionen ein ausführbares Image zum Debuggen konfigurieren. Sie können die JIT-Kompilierung auf nahezu gleiche Weise auch für das Debuggen konfigurieren.

Diese JIT-Konfiguration hat zwei Aspekte:

  • Sie können den JIT-Compiler anweisen, Nachverfolgungsinformationen zu generieren. Dadurch kann der Debugger eine CIL-Kette dem entsprechenden Computercode zuordnen und verfolgen, wo lokale Variablen und Funktionsargumente gespeichert werden. In .NET Framework, Version 2.0 und höher, generiert der JIT-Compiler immer Nachverfolgungsinformationen, daher ist es eine explizite Anforderung nicht erforderlich.

  • Sie können den JIT-Compiler anweisen, den erzeugten Computercode nicht zu optimieren.

Normalerweise legt der Compiler, der die CIL generiert, diese JIT-Compileroptionen entsprechend fest. Sie basieren auf den angegebenen IDE-Schaltern oder Befehlszeilenoptionen, die Sie angeben (z. B. /Od).

Mitunter kann es erforderlich sein, das Verhalten des JIT-Compilers zu ändern, sodass der generierte Computercode einfacher zu debuggen ist. So können Sie z. B. JIT-Verfolgungsinformationen für eine Verkaufsversion generieren oder die Optimierung steuern. Dazu können Sie eine Initialisierungsdatei (INI) verwenden.

Beispiel: Wenn die zu debuggende Assembly MyApp.exe heißt, erstellen Sie in dem Ordner, in dem MyApp.exe gespeichert ist, eine Textdatei mit dem Namen MyApp.ini, die die folgenden drei Zeilen enthält:

[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0

Sie können für die Optionen jeweils den Wert 0 oder 1 einstellen. Nicht vorhandene Optionen haben standardmäßig den Wert 0. Am einfachsten lässt sich die Assembly debuggen, wenn Sie für GenerateTrackingInfo 1 und für AllowOptimize 0 festlegen.

Ab .NET Framework Version 2.0 generiert der JIT-Compiler unabhängig vom Wert für GenerateTrackingInfo immer Nachverfolgungsinformationen. Der AllowOptimize-Wert ist jedoch weiterhin gültig. Wenn Sie das native Image mithilfe von Ngen.exe (Native Image Generator) ohne Optimierung vorkompilieren, muss bei der Ausführung von „Ngen.exe“ die INI-Datei im Zielordner mit der Einstellung AllowOptimize=0 vorhanden sein. Falls Sie eine Assembly ohne Optimierung vorkompiliert haben, müssen Sie den vorkompilierten Code mit der Ngen.exe-Option /uninstall entfernen, bevor Sie „Ngen.exe“ erneut ausführen, um den Code in optimierter Form vorzukompilieren. Wenn im Ordner keine .ini-Datei vorhanden ist, kompiliert Ngen.exe den Code standardmäßig optimiert vor.

System.Diagnostics.DebuggableAttribute kontrolliert die Einstellungen für eine Assembly. DebuggableAttribute enthält zwei Felder, die steuern, ob der JIT-Compiler eine Optimierung durchführen und/oder Nachverfolgungsinformationen generieren soll. In .NET Framework 2.0 und höheren Versionen generiert der JIT-Compiler immer Nachverfolgungsinformationen.

Bei Verkaufsversionen legen Compiler das Attribut DebuggableAttribute nicht fest. Standardmäßig generiert der JIT-Compiler den Computercode mit der höchsten Leistung, der sich am schwierigsten debuggen lässt. Durch Aktivieren der JIT-Verfolgung wird die Leistung geringfügig, durch Deaktivieren der Optimierung erheblich verschlechtert.

DebuggableAttribute gilt immer für die gesamte Assembly, nicht für einzelne Module innerhalb der Assembly. Aus diesem Grund müssen Entwicklungstools benutzerdefinierte Attribute an das Metadatentoken der Assembly anfügen, sofern bereits eine Assembly erstellt wurde oder aber an die System.Runtime.CompilerServices.AssemblyAttributesGoHere-Klasse. Das ALink-Tool gibt diese DebuggableAttribute-Attribute aus den einzelnen Modulen dann an die Assembly weiter, deren Bestandteil sie werden. Im Fall eines Konflikts tritt beim ALink-Vorgang ein Fehler auf.

Hinweis

In Version 1.0 von .NET Framework fügt der Microsoft Visual C++-Compiler das DebuggableAttribute hinzu, wenn die Compileroptionen /clr und /Zi angegeben werden. In Version 1.1 von .NET Framework müssen Sie entweder das DebuggableAttribute manuell im Code hinzufügen oder die Linkeroption /ASSEMBLYDEBUG verwenden.

Weitere Informationen