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 typu 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 próbę dekompilacji. Mimo że atrybut jest przestarzały na platformie .NET 6 lub nowszym, program Visual Studio honoruje atrybut .

Generowanie kodu źródłowego

W przypadku debugowania i braku dostępnego 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 załadowanych symboli. 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 załadowanych symboli.

Screenshot of no symbol loaded document

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

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

Screenshot of source not found document

Kod autokompiluj

Począwszy od programu Visual Studio 2022 w wersji 17.7, debuger programu Visual Studio obsługuje autokompilację zewnętrznego kodu platformy .NET. Autokompilowanie można wykonać podczas przechodzenia do kodu zewnętrznego lub w oknie 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, pozycja Just My Code musi być wyłączona.

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

Aby automatycznie skompilować 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.

    Screenshot of Call Stack window showing external code.

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

    Screenshot of External Sources node showing decompiled assemblies.

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

Aby wyłączyć automatyczne dekompilowanie kodu zewnętrznego, przejdź do pozycji Narzędzia > Opcje > Debugowanie > ogólne i usuń zaznaczenie opcji Automatycznie dekompiluj do źródła, jeśli jest to konieczne (tylko zarządzane).

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ły 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żesz wyodrębnić osadzony kod źródłowy.

Screenshot of assembly context menu in modules window with decompile source command.

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ębnij kod źródłowy w menu kontekstowym okna Moduły .

Screenshot of assembly context menu in modules window with extract sources command.

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. Tę funkcję można włączyć za pomocą pola wyboru Narzędzia>Opcje>dokumenty>środowiska>Pokaż różne pliki w Eksplorator rozwiązań. Jeśli ta funkcja nie jest włączona, nie można otworzyć wyodrębnionego kodu źródłowego.

Screenshot of tools option page with miscellaneous files option enabled.

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

Screenshot of solution explorer with miscellaneous files.

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ą linku źródłowego i Poprawianie produktywności czasu debugowania za pomocą funkcji 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 wyzwolić program Visual Studio, aby przerwać następny czas uruchamiania kodu przy użyciu polecenia Break All (Break all icon).

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 zestawów zoptymalizowanych lub wydań

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

  • Punkty przerwania mogą nie zawsze wiązać się z zgodną lokalizacją określania źródła.
  • Krok po kroku może nie zawsze przejść 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 temacie Problem z usługą GitHub: integracja ICSharpCode.Decompiler z debugerem programu VS.

Niezawodność dekompilacji

Stosunkowo niewielki procent prób dekompilacji może spowodować niepowodzenie. To zachowanie jest spowodowane błędem odwołania null punktu sekwencji 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 temacie Problem z usługą GitHub: integracja ICSharpCode.Decompiler z debugerem programu VS.

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 funkcji ILSpy asynchronicznego/await i zwracania maszyn stanowych jest implementowana tylko częściowo.

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 Moduły pokazuje, które moduły kodu debuger traktuje jako Mój kod (kod użytkownika).

Dekompilacja zoptymalizowanych lub wydań modułów generuje kod nieużytkownika. Jeśli debuger przerwie w dekompilowany kod nieużytkownika, na przykład zostanie wyświetlone okno Brak źródła . Aby wyłączyć tylko mój kod, przejdź do pozycji Narzędzia>Opcje (lub Opcje debugowania>) >Debugowanie>ogólne, a następnie usuń zaznaczenie pozycji 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 każda hierarchia folderów, z którą oryginalne źródła nie zostały użyte.
  • 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.