Udostępnij za pomocą


Debugowanie zoptymalizowanego kodu

W tym artykule wyjaśniono, które przełączniki kompilatora mają być ustawione, aby umożliwić lepsze debugowanie zoptymalizowanego kodu.

Lepsze doświadczenie jest dostępne od programu Visual Studio 2022 w wersji 17.14, które umożliwia debugowanie zoptymalizowanego kodu, tak jakby był skompilowany niezoptymalizowany, zachowując jednocześnie szybkość zoptymalizowanego kodu. Aby uzyskać więcej informacji, zobacz debugowanie dynamiczne języka C++ (wersja zapoznawcza).

Uwaga

Wyświetlane okna dialogowe i polecenia menu mogą się różnić od tych opisanych w sekcji Pomoc w zależności od aktywnych ustawień lub edycji. Aby zmienić ustawienia, wybierz pozycję Importuj i eksportuj ustawienia w menu narzędzia . Aby uzyskać więcej informacji, zobacz Resetuj wszystkie ustawienia.

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 zawsze może zidentyfikować kod źródłowy odpowiadający zestawowi instrukcji.

Optymalizacja może mieć wpływ na:

  • Optymalizator może usuwać zmienne lokalne lub przenosić je do lokalizacji, których debuger nie rozumie.

  • Pozycje wewnątrz funkcji, które są zmieniane, gdy optymalizator scala bloki kodu.

  • Nazwy ramek funkcji w stosie wywołań mogą 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 asemblera, lub jeśli w stosie wywołań znajdują się ramki systemu operacyjnego bez pasujących symboli.

    Zmienne globalne i statyczne są zawsze wyświetlane poprawnie. Podobnie jest z układem 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 Debug

  1. Podczas tworzenia nowego projektu wybierz element docelowy Win32 Debug . Używaj celu Win32 Debug dopóki program nie zostanie w pełni debugowany i będziesz gotowy na stworzenie celu Win32 Release. Kompilator nie optymalizuje obiektu docelowego Win32 Debug.

  2. Wybierz projekt w Eksploratorze 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 w liście rozwijanej Konfiguracja jest wybrane Debug.

  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 określa 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 węzeł 'Wiersz polecenia' w sekcji C/C++ w Właściwościach konfiguracji na stronie właściwości projektu, a następnie dodaj (/Zo) do pola tekstowego Opcje dodatkowe.

    Ostrzeżenie

    Dodawanie /Zo powoduje wyłączenie opcji Edytuj i Kontynuuj.

    Podczas debugowania zoptymalizowanego kodu użyj okna Dezasemblacja , aby zobaczyć, jakie instrukcje zostały 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 to poza pętlę. Punkt przerwania porusza się z nim. Instrukcje, które porównują i zwiększają x, pozostają wewnątrz pętli. Przy wyświetlaniu okna Dezasemblacji, jednostka kroku jest automatycznie ustawiana na instrukcję dla większej kontroli, co jest przydatne podczas przechodzenia przez zoptymalizowany kod.