Udostępnij za pośrednictwem


Generowanie kodu źródłowego na podstawie zestawów platformy .NET podczas debugowania

Podczas debugowania aplikacji .NET może się okazać, że chcesz wyświetlić kod źródłowy, którego nie masz. Na przykład przerwanie wyjątku lub użycie stosu wywołań w celu przejścia do lokalizacji źródłowej.

Uwaga

  • Generowanie kodu źródłowego (dekompilacji) jest dostępne tylko dla aplikacji platformy .NET i jest oparte na projekcie ILSpy open source.
  • Dekompilacja jest dostępna tylko w programie Visual Studio 2019 16.5 lub nowszym.
  • Zastosowanie atrybutu SuppressIldasmAttribute do zestawu lub modułu uniemożliwia programowi Visual Studio podjęcie próby dekompilacji. Mimo że atrybut jest przestarzały na platformie .NET 6 lub nowszym, program Visual Studio honoruje atrybut .

Generowanie kodu źródłowego

Podczas debugowania i braku kodu źródłowego program Visual Studio wyświetla dokument Nie znaleziono źródła lub jeśli nie masz symboli dla zestawu, dokument Brak symboli załadowanych. Oba dokumenty mają opcję Dekompiluj kod źródłowy, która generuje kod języka C# dla bieżącej lokalizacji. Wygenerowany kod języka C# może być następnie używany podobnie jak w przypadku każdego innego kodu źródłowego. Możesz wyświetlić kod, sprawdzić zmienne, ustawić punkty przerwania itd.

Brak załadowanych symboli

Na poniższej ilustracji przedstawiono komunikat Brak symboli załadowanych.

Zrzut ekranu dokumentu z brakiem załadowanego symbolu

Nie można odnaleźć źródła

Poniższa ilustracja przedstawia komunikat Nie znaleziono źródła.

Zrzut ekranu dokumentu źródłowego nie znaleziono

Kod autodekompilacji

Począwszy od programu Visual Studio 2022 w wersji 17.7, debuger programu Visual Studio obsługuje autokompilację zewnętrznego kodu platformy .NET. Automatyczna dekompilacja może być wykonywana podczas wchodzenia do kodu zewnętrznego lub przy użyciu okna stosu wywołań.

Jeśli wprowadzisz kod zaimplementowany zewnętrznie, debuger automatycznie je zdekompiluje i wyświetli bieżący punkt wykonywania. Jeśli chcesz przejść do kodu zewnętrznego, wyłącz Just My Code.

Można dekompilować z okna stosu wywołań bez wyłączania opcji Tylko mój kod.

Aby automatycznie dekompilować z okna stosu wywołań:

  1. Podczas debugowania przy użyciu otwartego okna stosu wywołań wybierz pozycję Pokaż kod zewnętrzny.

  2. W oknie Stos wywołań kliknij dwukrotnie dowolną ramkę stosu. Debuger dekompiluje kod, a następnie przechodzi bezpośrednio do bieżącego punktu wykonywania.

    Zrzut ekranu okna stosu wywołań pokazujący kod zewnętrzny.

    Cały dekompilowany kod jest również wyświetlany w węźle Źródła zewnętrzne w Eksploratorze rozwiązań, co ułatwia przeglądanie plików zewnętrznych w razie potrzeby.

    Zrzut ekranu przedstawiający węzeł Źródła zewnętrzne z dekompilowanych zestawów.

    Można debugować zdekompilowany kod i ustawić punkty przerwania.

Aby wyłączyć automatyczne dekompilowanie kodu zewnętrznego, przejdź do Narzędzia > Opcje > Debugowanie > Ogólne i odznacz opcję Automatyczne dekompilowanie do kodu źródłowego w razie potrzeby (tylko dla kodu zarządzanego).

Generowanie i osadzanie źródeł dla zestawu

Oprócz generowania kodu źródłowego dla określonej lokalizacji można wygenerować cały kod źródłowy dla danego zestawu platformy .NET. Aby wykonać to zadanie, przejdź do okna modułów i z menu kontekstowego zestawu .NET, a następnie wybierz polecenie Dekompiluj źródło do pliku symboli. Program Visual Studio generuje plik symboli dla zestawu, a następnie osadza źródło w pliku symboli. W późniejszym kroku można wyodrębnić osadzony kod źródłowy.

Zrzut ekranu przedstawiający menu kontekstowe zestawu w oknie modułów z poleceniem dekompilowania źródła.

Wyodrębnianie i wyświetlanie osadzonego kodu źródłowego

Pliki źródłowe osadzone w pliku symboli można wyodrębnić przy użyciu polecenia Wyodrębnianie kodu źródłowego w menu kontekstowym okna Moduły.

Zrzut ekranu przedstawiający menu kontekstowe zestawu w oknie modułów z poleceniem wyodrębniania źródeł.

Wyodrębnione pliki źródłowe są dodawane do rozwiązania jako różne pliki. Funkcja różnych plików jest domyślnie wyłączona w programie Visual Studio. Można włączyć tę funkcję w Narzędziach Tools>Opcje>Środowisko>Dokumenty>zaznaczając pole wyboru "Pokaż różne pliki w Eksploratorze rozwiązań". Jeśli ta funkcja nie jest włączona, nie można otworzyć wyodrębnionego kodu źródłowego.

Zrzut ekranu przedstawiający stronę opcji narzędzi z włączoną opcją różnych plików.

Wyodrębnione pliki źródłowe są wyświetlane w różnych plikach w Eksploratorze rozwiązań .

Zrzut ekranu eksploratora rozwiązań z różnymi plikami.

W przypadku bibliotek platformy .NET lub pakietów NuGet z włączoną funkcją SourceLink można również przejść do kodu źródłowego, ustawić punkty przerwania i użyć wszystkich funkcji debugera. Aby uzyskać więcej informacji, zobacz Włączanie debugowania i diagnostyki za pomocą Source Link oraz Poprawa produktywności podczas debugowania z SourceLink.

Znane ograniczenia

Wymaga trybu przerwania

Generowanie kodu źródłowego przy użyciu dekompilacji jest możliwe tylko wtedy, gdy debuger jest w trybie przerwania i aplikacja jest wstrzymana. Na przykład program Visual Studio wprowadza tryb przerwania po osiągnięciu punktu przerwania lub wyjątku. Możesz łatwo sprawić, że Visual Studio przerwie działanie przy następnym uruchomieniu kodu, używając polecenia Break All (ikona 'Przerwij wszystko').

Ograniczenia dekompilacji

Generowanie kodu źródłowego z formatu pośredniego (IL) używanego w zestawach platformy .NET ma pewne ograniczenia. W związku z tym wygenerowany kod źródłowy nie wygląda jak oryginalny kod źródłowy. Większość różnic jest w miejscach, w których informacje w oryginalnym kodzie źródłowym nie są potrzebne w czasie wykonywania. Na przykład informacje takie jak białe znaki, komentarze i nazwy zmiennych lokalnych nie są potrzebne w czasie wykonywania. Zalecamy użycie wygenerowanego źródła, aby zrozumieć, jak program wykonuje, a nie jako zamiennik oryginalnego kodu źródłowego.

Debugowanie zoptymalizowanych lub wydanych zestawów

Podczas debugowania kodu dekompilowanego z zestawu skompilowanego przy użyciu optymalizacji kompilatora mogą wystąpić następujące problemy:

  • Punkty przerwania mogą nie zawsze powiązać się z odpowiednią lokalizacją źródłową.
  • Krok może nie zawsze prowadzić do właściwej lokalizacji.
  • Zmienne lokalne mogą nie mieć dokładnych nazw.
  • Niektóre zmienne mogą nie być dostępne do oceny.

Więcej szczegółów można znaleźć w problemie na GitHub: integracja ICSharpCode.Decompiler z debuggerem VS.

Niezawodność dekompilacji

Stosunkowo niewielki procent prób dekompilacji może spowodować niepowodzenie. To zachowanie jest spowodowane błędem null reference w punkcie sekwencyjnym w ILSpy. Wyeliminowaliśmy ten błąd, przechwycąc te problemy i bezpiecznie kończąc próbę dekompilacji.

Więcej szczegółów można znaleźć w kwestii GitHub: integracja ICSharpCode.Decompiler z VS Debugger.

Ograniczenia dotyczące kodu asynchronicznego

Wyniki dekompilowania modułów z wzorcami kodu asynchronicznego/await mogą być niekompletne lub całkowicie zakończyć się niepowodzeniem. Implementacja maszyn stanów async/await i yield w ILSpy jest tylko częściowo zrealizowana.

Więcej szczegółów można znaleźć w temacie Problem z usługą GitHub: stan generatora PDB.

Tylko mój kod

Ustawienie Just My Code (JMC) umożliwia programowi Visual Studio przechodzenie przez system, platformę, bibliotekę i inne wywołania nieużytkownika. Podczas sesji debugowania okno Modules pokazuje, które moduły kodu debugera traktują jako Mój kod (kod użytkownika).

Dekompilacja zoptymalizowanych lub wydanych modułów generuje kod innym niż użytkownik. Jeśli debuger przerwie w dekompilowany kod nieużytkownika, na przykład zostanie wyświetlone okno Brak źródła. Aby wyłączyć opcję Tylko mój kod, przejdź do Tools>Options (lub Debuguj opcje>) >Debugowanie>Ogólne, a następnie usuń zaznaczenie Włącz tylko mój kod.

Wyodrębnione źródła

Kod źródłowy wyodrębniony z zestawu ma następujące ograniczenia:

  • Nazwa i lokalizacja wygenerowanych plików nie można skonfigurować.
  • Pliki są tymczasowe i usuwane przez program Visual Studio.
  • Pliki są umieszczane w jednym folderze, a hierarchia folderów oryginalnych źródeł nie jest wykorzystywana.
  • Nazwa pliku dla każdego pliku zawiera skrót sumy kontrolnej pliku.

Wygenerowany kod jest tylko w języku C#

Dekompilacja generuje tylko pliki kodu źródłowego w języku C#. Nie ma możliwości generowania plików w żadnym innym języku.