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

  1. 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 skompilowania Win32 Release elementu docelowego. Kompilator nie optymalizuje Win32 Debug obiektu docelowego.

  2. Wybierz projekt w Eksplorator rozwiązań.

  3. W menu Widok kliknij pozycję Strony właściwości.

  4. W oknie dialogowym Strony właściwości upewnij się, że Debug wybrano opcję na liście rozwijanej Konfiguracja.

  5. W widoku folderu po lewej stronie wybierz folder C/C++ .

  6. W folderze C++ wybierz pozycję Optimization.

  7. Na liście właściwości po prawej stronie znajdź pozycję Optimization. Ustawienie obok niego prawdopodobnie mówi Disabled (/Od). Wybierz jedną z pozostałych opcji (Minimum Size``(/O1), Maximum Speed``(/O2), Full Optimization``(/Ox) lub Custom).

  8. Jeśli wybrano Custom opcję dla opcji Optimization, możesz teraz ustawić opcje dla dowolnej z innych właściwości pokazanych na liście właściwości.

  9. 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.