Zbieranie szczegółowych informacji o ładowaniu zestawu
Począwszy od platformy .NET 5, środowisko uruchomieniowe może emitować zdarzenia za pomocą EventPipe
szczegółowych informacji o ładowaniu zestawu zarządzanego, aby ułatwić diagnozowanie problemów z ładowaniem zestawu. Te zdarzenia są emitowane przez dostawcę Microsoft-Windows-DotNETRuntime
w ramach słowa kluczowego AssemblyLoader
(0x4
).
Wymagania wstępne
- Zestaw .NET 5 SDK lub nowsze wersje
dotnet-trace
Narzędzie
Uwaga
Zakres dotnet-trace
możliwości jest większy niż zbieranie szczegółowych informacji o ładowaniu zestawu. Aby uzyskać więcej informacji na temat użycia programu dotnet-trace
, zobacz dotnet-trace
.
Zbieranie śledzenia ze zdarzeniami ładowania zestawu
dotnet-trace
Służy do śledzenia istniejącego procesu lub uruchamiania procesu podrzędnego i śledzenia go z uruchamiania.
Śledzenie istniejącego procesu
Aby włączyć zdarzenia ładowania zestawu w środowisku uruchomieniowym i zebrać ich ślad, użyj dotnet-trace
następującego polecenia:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id <pid>
To polecenie zbiera ślad określonego <pid>
obiektu , włączając AssemblyLoader
zdarzenia u dostawcy Microsoft-Windows-DotNETRuntime
. Wynik jest plikiem .nettrace
.
Użyj polecenia dotnet-trace, aby uruchomić proces podrzędny i prześledzić go z uruchamiania
Czasami przydatne może być zebranie śladu procesu od jego uruchomienia. W przypadku aplikacji z platformą .NET 5 lub nowszym można użyć dotnet-trace
jej do wykonania.
Następujące polecenie uruchamia hello.exe za pomocą arg1
polecenia i arg2
jako argumenty wiersza polecenia i zbiera ślad z uruchamiania środowiska uruchomieniowego:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 -- hello.exe arg1 arg2
Możesz zatrzymać zbieranie śladu, naciskając klawisz Enter lub Ctrl + C. Spowoduje to również zamknięcie hello.exe.
Uwaga
- Uruchamianie hello.exe za pośrednictwem
dotnet-trace
przekierowania jego danych wejściowych i wyjściowych i nie będzie można domyślnie korzystać z niego w konsoli. Użyj przełącznika--show-child-io
, aby wchodzić w interakcje z elementamistdin
istdout
. - Zamknięcie narzędzia za pomocą kombinacji klawiszy Ctrl+C lub
SIGTERM
bezpieczne zakończenie zarówno narzędzia, jak i procesu podrzędnego. - Jeśli proces podrzędny zakończy się przed narzędziem, narzędzie również zakończy działanie, a ślad powinien być bezpiecznie wyświetlany.
Wyświetlanie śladu
Zebrany plik śledzenia można wyświetlić w systemie Windows przy użyciu widoku Zdarzenia w programie PerfView. Wszystkie zdarzenia ładowania zestawu będą poprzedzone prefiksem Microsoft-Windows-DotNETRuntime/AssemblyLoader
.
Przykład (w systemie Windows)
W tym przykładzie użyto przykładu punktów rozszerzenia ładowania zestawu. Aplikacja próbuje załadować zestaw MyLibrary
— zestaw, do którego nie odwołuje się aplikacja, i dlatego wymaga pomyślnego załadowania obsługi w punkcie rozszerzenia ładowania zestawu.
Zbieranie śladu
Przejdź do katalogu przy użyciu pobranego przykładu. Skompiluj aplikację za pomocą następujących funkcji:
dotnet build
Uruchom aplikację z argumentami wskazującymi, że powinna zostać wstrzymana, czekając na naciśnięcie klawisza. Po wznowieniu podejmie próbę załadowania zestawu domyślnie
AssemblyLoadContext
— bez obsługi niezbędnej do pomyślnego załadowania. Przejdź do katalogu wyjściowego i uruchom polecenie:AssemblyLoading.exe /d default
Znajdź identyfikator procesu aplikacji.
dotnet-trace ps
Dane wyjściowe będą zawierać listę dostępnych procesów. Na przykład:
35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
Dołącz
dotnet-trace
do uruchomionej aplikacji.dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
W oknie z uruchomioną aplikacją naciśnij dowolny klawisz, aby umożliwić kontynuowanie programu. Śledzenie zostanie automatycznie zatrzymane po zakończeniu działania aplikacji.
Wyświetlanie śladu
Otwórz zebrany ślad w widoku PerfView i otwórz widok Zdarzenia. Filtruj listę zdarzeń do Microsoft-Windows-DotNETRuntime/AssemblyLoader
zdarzeń.
Zostaną wyświetlone wszystkie obciążenia zestawów, które wystąpiły w aplikacji po rozpoczęciu śledzenia. Aby sprawdzić operację ładowania dla zestawu zainteresowań w tym przykładzie — MyLibrary
możemy wykonać więcej filtrowania.
Ładowanie zestawów
Filtruj widok do zdarzeń Start
i Stop
w obszarze Microsoft-Windows-DotNETRuntime/AssemblyLoader
przy użyciu listy zdarzeń po lewej stronie. Dodaj kolumny AssemblyName
, ActivityID
i Success
do widoku. Filtruj do zdarzeń zawierających MyLibrary
.
Nazwa zdarzenia | Assemblyname | Identyfikator działania | Powodzenie |
---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
1/2/ | |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
1/2/ | Fałsz |
Powinna zostać wyświetlona jedna Start
/Stop
para z Success=False
zdarzeniem Stop
wskazująca, że operacja ładowania nie powiodła się. Należy pamiętać, że dwa zdarzenia mają ten sam identyfikator działania. Identyfikator działania może służyć do filtrowania wszystkich innych zdarzeń modułu ładującego zestawów tylko do tych odpowiadających tej operacji ładowania.
Podział próby załadowania
Aby uzyskać bardziej szczegółowy podział operacji ładowania, przefiltruj widok do ResolutionAttempted
zdarzeń w obszarze Microsoft-Windows-DotNETRuntime/AssemblyLoader
przy użyciu listy zdarzeń po lewej stronie. Dodaj kolumny AssemblyName
, Stage
i Result
do widoku. Filtruj do zdarzeń przy użyciu identyfikatora Start
/Stop
działania z pary.
Nazwa zdarzenia | Assemblyname | Etap | Result |
---|---|---|---|
AssemblyLoader/ResolutionAttempted |
MyLibrary, Culture=neutral, PublicKeyToken=null |
FindInLoadContext |
AssemblyNotFound |
AssemblyLoader/ResolutionAttempted |
MyLibrary, Culture=neutral, PublicKeyToken=null |
ApplicationAssemblies |
AssemblyNotFound |
AssemblyLoader/ResolutionAttempted |
MyLibrary, Culture=neutral, PublicKeyToken=null |
AssemblyLoadContextResolvingEvent |
AssemblyNotFound |
AssemblyLoader/ResolutionAttempted |
MyLibrary, Culture=neutral, PublicKeyToken=null |
AppDomainAssemblyResolveEvent |
AssemblyNotFound |
Powyższe zdarzenia wskazują, że moduł ładujący zestaw próbował rozwiązać problem, patrząc w bieżącym kontekście ładowania, uruchamiając domyślną logikę sondowania dla zarządzanych zestawów aplikacji, wywołując programy obsługi dla AssemblyLoadContext.Resolving zdarzenia i wywołując programy obsługi dla elementu AppDomain.AssemblyResolve. W przypadku wszystkich tych kroków zestaw nie został znaleziony.
Punkty rozszerzenia
Aby sprawdzić, które punkty rozszerzenia zostały wywołane, przefiltruj widok do AssemblyLoadContextResolvingHandlerInvoked
elementu i AppDomainAssemblyResolveHandlerInvoked
w obszarze Microsoft-Windows-DotNETRuntime/AssemblyLoader
przy użyciu listy zdarzeń po lewej stronie. Dodaj kolumny AssemblyName
i HandlerName
do widoku. Filtruj do zdarzeń przy użyciu identyfikatora Start
/Stop
działania z pary.
Nazwa zdarzenia | Assemblyname | Nazwa programu obsługi |
---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAppDomainAssemblyResolve |
Powyższe zdarzenia wskazują, że dla zdarzenia wywołano program obsługi o nazwie OnAssemblyLoadContextResolving
, a program AssemblyLoadContext.Resolving obsługi o nazwie OnAppDomainAssemblyResolve
został wywołany dla AppDomain.AssemblyResolve zdarzenia.
Zbieranie innego śladu
Uruchom aplikację z argumentami, tak aby jego program obsługi dla AssemblyLoadContext.Resolving zdarzenia załadował MyLibrary
zestaw.
AssemblyLoading /d default alc-resolving
Zbierz i otwórz inny .nettrace
plik, wykonując kroki opisane powyżej.
Filtruj do zdarzeń Start
i Stop
, aby ponownie MyLibrary
. Powinna zostać wyświetlona Start
/Stop
para z inną Start
/Stop
między nimi. Operacja ładowania wewnętrznego reprezentuje obciążenie wyzwalane przez program obsługi po AssemblyLoadContext.Resolving wywołaniu AssemblyLoadContext.LoadFromAssemblyPathmetody . Tym razem powinno zostać wyświetlone Success=True
Stop
zdarzenie wskazujące, że operacja ładowania zakończyła się pomyślnie. Pole ResultAssemblyPath
zawiera ścieżkę wynikowego zestawu.
Nazwa zdarzenia | Assemblyname | Identyfikator działania | Powodzenie | ResultAssemblyPath |
---|---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
1/2/ | ||
AssemblyLoader/Start |
MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
1/2/1/ | ||
AssemblyLoader/Stop |
MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
1/2/1/ | Prawda | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
1/2/ | Prawda | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Następnie możemy przyjrzeć się ResolutionAttempted
zdarzeń o identyfikatorze działania z obciążenia zewnętrznego, aby określić krok, w którym zestaw został pomyślnie rozwiązany. Tym razem zdarzenia pokażą, że AssemblyLoadContextResolvingEvent
etap zakończył się pomyślnie. Pole ResultAssemblyPath
zawiera ścieżkę wynikowego zestawu.
Nazwa zdarzenia | Assemblyname | Etap | Result | ResultAssemblyPath |
---|---|---|---|---|
AssemblyLoader/ResolutionAttempted |
MyLibrary, Culture=neutral, PublicKeyToken=null |
FindInLoadContext |
AssemblyNotFound |
|
AssemblyLoader/ResolutionAttempted |
MyLibrary, Culture=neutral, PublicKeyToken=null |
ApplicationAssemblies |
AssemblyNotFound |
|
AssemblyLoader/ResolutionAttempted |
MyLibrary, Culture=neutral, PublicKeyToken=null |
AssemblyLoadContextResolvingEvent |
Success |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Patrząc na AssemblyLoadContextResolvingHandlerInvoked
zdarzenia, program obsługi o nazwie OnAssemblyLoadContextResolving
został wywołany. Pole ResultAssemblyPath
zawiera ścieżkę zestawu zwróconego przez program obsługi.
Nazwa zdarzenia | Assemblyname | Nazwa programu obsługi | ResultAssemblyPath |
---|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Należy pamiętać, że nie ma już ResolutionAttempted
zdarzenia ze AppDomainAssemblyResolveEvent
etapem lub żadnym AppDomainAssemblyResolveHandlerInvoked
zdarzeniem, ponieważ zestaw został pomyślnie załadowany przed osiągnięciem kroku algorytmu ładowania, który zgłasza AppDomain.AssemblyResolve zdarzenie.