Debuggen von optimiertem Code
Hinweis
Je nach den aktiven Einstellungen oder der Version unterscheiden sich die Dialogfelder und Menübefehle auf Ihrem Bildschirm möglicherweise von den in der Hilfe beschriebenen. Klicken Sie im Menü Extras auf Einstellungen importieren und exportieren , um die Einstellungen zu ändern. Weitere Informationen finden Sie unter Alle Einstellungen zurücksetzen.
Hinweis
Die Compileroption /Zo (erweitertes optimiertes Debugging) (eingeführt in Visual Studio Update 3) generiert umfassendere Debuginformationen für optimierten Code (Projekte, die nicht mit der Compileroption /Od erstellt wurden. Siehe /O-Optionen (Code optimieren)). Dazu gehört verbesserte Unterstützung zum Debuggen von lokalen Variablen und Inlinefunktionen.
Bearbeiten und Fortfahren ist deaktiviert, wenn die /Zo-Compileroption verwendet wird.
Wenn der Compiler Code optimiert, werden die Anweisungen neu positioniert und organisiert. Hierdurch wird die Effizienz des kompilierten Codes erhöht. Aufgrund dieser Neuanordnung ist der Debugger nicht immer in der Lage, den Quellcode, der einer bestimmten Gruppe von Anweisungen entspricht, zu erkennen.
Durch die Optimierung können folgende Bereiche beeinflusst werden:
Lokale Variablen, die durch den Optimierer entfernt oder an Speicherorte verschoben werden können, die vom Debugger nicht erkannt werden.
Positionen in einer Funktion, die geändert werden, wenn Codeblöcke durch den Optimierer zusammenführt werden.
Funktionsnamen für Rahmen der Aufrufliste, die möglicherweise falsch sind, wenn der Optimierer zwei Funktionen zusammenführt.
Die in der Aufrufliste angezeigten Rahmen sind fast immer korrekt, vorausgesetzt, es sind für alle Rahmen Symbole vorhanden. Die Rahmen der Aufrufliste sind falsch, wenn die Aufrufliste beschädigt ist, wenn Funktionen in der Assemblysprache geschrieben wurden oder wenn es sich um Betriebssystemrahmen ohne entsprechende Symbole in der Aufrufliste handelt.
Globale und statische Variablen werden immer richtig angezeigt. Dies trifft auch auf das Strukturlayout zu. Wenn ein Zeiger auf eine Struktur vorhanden und der Wert des Zeigers richtig ist, zeigt jede Membervariable der Struktur den richtigen Wert an.
Aufgrund dieser Einschränkungen müssen Debugoperationen, wenn überhaupt möglich, unter Verwendung einer nicht optimierten Version des Programms erfolgen. In der Debugkonfiguration eines C++-Programms ist die Optimierung standardmäßig deaktiviert, während sie in der Releasekonfiguration aktiviert ist.
Ein Fehler ist jedoch nur in einer optimierten Programmversion erkennbar. In diesem Fall muss der optimierte Code gedebuggt werden.
So aktivieren Sie die Optimierung in einer Debugbuildkonfiguration
Wählen Sie beim Erstellen eines neuen Projekts
Win32 Debug
als Ziel aus. Verwenden Sie dasWin32 Debug
-Ziel, bis das Programm vollständig debuggt und für die Erstellung einesWin32 Release
-Ziels bereit ist. DasWin32 Debug
-Ziel wird nicht vom Compiler optimiert.Wählen Sie das Projekt im Projektmappen-Explorer aus.
Klicken Sie im Menü Ansicht auf die Option Eigenschaftenseiten.
Stellen Sie im Dialogfeld Eigenschaftenseiten sicher, dass die Option
Debug
in der Dropdownliste Konfiguration ausgewählt ist.Wählen Sie in der Ordneransicht auf der linken Seite den Ordner C/C++ aus.
Wählen Sie
Optimization
im Ordner C++ aus.Suchen Sie die Option
Optimization
in der Eigenschaftenliste auf der rechten Seite. Die Einstellung daneben lautet vermutlichDisabled (
/Od)
. Wählen Sie eine der anderen Optionen aus (Minimum Size``(
/O1)
,Maximum Speed``(
/O2)
,Full Optimization``(
/Ox)
oderCustom
).Wenn Sie für die
Custom
die OptionOptimization
auswählen, können Sie Optionen für alle weiteren Eigenschaften in der Eigenschaftenliste festlegen.Wählen Sie den C/C++-Befehlszeilenknoten „Konfigurationseigenschaften“ der Eigenschaftenseite des Projekts aus, und fügen Sie
(
/Zo)
dem Textfeld Weitere Optionen hinzu.Warnung
Das Hinzufügen von
/Zo
deaktiviert Bearbeiten und Fortfahren.Ermitteln Sie beim Debuggen von optimiertem Code im Fenster Disassemblierung, welche Anweisungen tatsächlich generiert und ausgeführt werden. Beim Festlegen von Haltepunkten sollten Sie beachten, dass der Haltepunkt zusammen mit einer Anweisung verschoben werden kann. Beachten Sie z. B. folgenden Code:
for (x=0; x<10; x++)
Angenommen, Sie haben in dieser Zeile einen Haltepunkt festgelegt. Sie gehen möglicherweise davon aus, dass der Haltepunkt 10 Mal getroffen wird. Wenn der Code optimiert ist, wird er jedoch nur einmal getroffen. Dies liegt daran, dass die erste Anweisung den Wert von x
auf 0 festlegt. Der Compiler erkennt, dass dies nur einmal durchgeführt werden muss und verschiebt es aus der Schleife. Gleichzeitig wird auch der Haltepunkt verschoben. Die Anweisungen zum Vergleichen und Heraufsetzen von x
verbleiben innerhalb der Schleife. Wenn Sie das Fenster Disassemblierung anzeigen, wird die Schritteinheit zur besseren Steuerung automatisch auf „Befehl“ festgelegt. Dies ist bei der schrittweisen Ausführung von optimiertem Code von Vorteil.