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.
Nie można odnaleźć źródła
Poniższa ilustracja przedstawia komunikat Nie znaleziono źródła.
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ń:
Podczas debugowania przy użyciu otwartego okna stosu wywołań wybierz pozycję Pokaż kod zewnętrzny.
W oknie Stos wywołań kliknij dwukrotnie dowolną ramkę stosu. Debuger dekompiluje kod, a następnie przechodzi bezpośrednio do bieżącego punktu wykonywania.
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.
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.
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.
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.
Wyodrębnione pliki źródłowe są wyświetlane w różnych plikach w Eksploratorze rozwiązań .
ŹródłoLink
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 ().
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.