Debugowanie zoptymalizowanego kodu
Uwaga
Okna dialogowe i polecenia menu mogą się różnić od tych opisanych w Pomocy, w zależności od ustawień aktywnych lub wydania. Aby zmienić ustawienia, wybierz pozycję Importuj i Eksportuj Ustawienia w menu Narzędzia. Aby uzyskać więcej informacji, zobacz Resetowanie wszystkich ustawień.
Uwaga
Opcja kompilatora /Zo (Ulepszone zoptymalizowane debugowanie) (wprowadzona w programie Visual Studio Update 3) generuje bogatsze informacje debugowania zoptymalizowanego kodu (projekty, które nie są kompilowane przy użyciu /Od opcji kompilatora. Zobacz /O Options (Optymalizuj kod)). Obejmuje to ulepszoną obsługę debugowania zmiennych lokalnych i wbudowanych funkcji.
Opcja Edytuj i Kontynuuj jest wyłączona, gdy jest używana opcja kompilatora /Zo .
Gdy kompilator optymalizuje kod, zmienia położenie i reorganizuje instrukcje. Spowoduje to zwiększenie wydajności skompilowanego kodu. Z powodu tego ponownego rozmieszczania debuger nie może zawsze identyfikować kodu źródłowego odpowiadającego zestawowi instrukcji.
Optymalizacja może mieć wpływ na:
Zmienne lokalne, które mogą zostać usunięte przez optymalizator lub przeniesione do lokalizacji, które debuger nie rozumie.
Pozycje wewnątrz funkcji, które są zmieniane, gdy optymalizator scala bloki kodu.
Nazwy funkcji ramek w stosie wywołań, co może być błędne, jeśli optymalizator scala dwie funkcje.
Ramki widoczne na stosie wywołań są prawie zawsze poprawne, jednak przy założeniu, że masz symbole dla wszystkich ramek. Ramki w stosie wywołań będą nieprawidłowe, jeśli masz uszkodzenie stosu, jeśli masz funkcje napisane w języku zestawu lub jeśli istnieją ramki systemu operacyjnego bez pasujących symboli na stosie wywołań.
Zmienne globalne i statyczne są zawsze wyświetlane poprawnie. Tak więc jest układ struktury. Jeśli masz wskaźnik do struktury, a wartość wskaźnika jest poprawna, każda zmienna składowa struktury będzie wyświetlać poprawną wartość.
Ze względu na te ograniczenia należy debugować przy użyciu niezoptymalizowanej wersji programu, jeśli w ogóle jest to możliwe. Domyślnie optymalizacja jest wyłączona w konfiguracji debugowania programu C++ i włączona w konfiguracji wydania.
Jednak usterka może pojawić się tylko w zoptymalizowanej wersji programu. W takim przypadku należy debugować zoptymalizowany kod.
Aby włączyć optymalizację w konfiguracji kompilacji debugowania
Podczas tworzenia nowego projektu wybierz element docelowy
Win32 Debug
.Win32 Debug
Użyj elementu docelowego, dopóki program nie zostanie w pełni debugowany i wszystko będzie gotowe do skompilowaniaWin32 Release
elementu docelowego. Kompilator nie optymalizujeWin32 Debug
obiektu docelowego.Wybierz projekt w Eksplorator rozwiązań.
W menu Widok kliknij pozycję Strony właściwości.
W oknie dialogowym Strony właściwości upewnij się, że
Debug
wybrano opcję na liście rozwijanej Konfiguracja.W widoku folderu po lewej stronie wybierz folder C/C++ .
W folderze C++ wybierz pozycję
Optimization
.Na liście właściwości po prawej stronie znajdź pozycję
Optimization
. Ustawienie obok niego prawdopodobnie mówiDisabled (
/Od)
. Wybierz jedną z pozostałych opcji (Minimum Size``(
/O1)
,Maximum Speed``(
/O2)
,Full Optimization``(
/Ox)
lubCustom
).Jeśli wybrano
Custom
opcję dla opcjiOptimization
, możesz teraz ustawić opcje dla dowolnej z innych właściwości pokazanych na liście właściwości.Wybierz pozycję Właściwości konfiguracji, C/C++, węzeł Wiersza polecenia strony właściwości projektu i dodaj
(
/Zo)
do pola tekstowego Opcje dodatkowe.Ostrzeżenie
Dodanie
/Zo
spowoduje wyłączenie opcji Edytuj i Kontynuuj.Podczas debugowania zoptymalizowanego kodu użyj okna Dezasemblacji , aby zobaczyć, jakie instrukcje zostały rzeczywiście utworzone i wykonane. Po ustawieniu punktów przerwania musisz wiedzieć, że punkt przerwania może zostać przeniesiony razem z instrukcją. Rozważmy na przykład następujący kod:
for (x=0; x<10; x++)
Załóżmy, że ustawisz punkt przerwania w tym wierszu. Można oczekiwać, że punkt przerwania zostanie trafiony 10 razy, ale jeśli kod jest zoptymalizowany, punkt przerwania zostanie osiągnięty tylko raz. Wynika to z faktu, że pierwsza instrukcja ustawia wartość x
na 0. Kompilator rozpoznaje, że należy to zrobić tylko raz i przenosi go z pętli. Punkt przerwania porusza się z nim. Instrukcje porównania i przyrostu x
pozostają wewnątrz pętli. Po wyświetleniu okna Dezasemblacji jednostka kroku jest automatycznie ustawiana na Instrukcja w celu uzyskania większej kontroli, co jest przydatne podczas przechodzenia przez zoptymalizowany kod.