Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
A partire da .NET 5, il runtime può generare eventi tramite EventPipe
con informazioni dettagliate sul caricamento di assembly gestiti per facilitare la diagnosi dei problemi di caricamento degli assembly. Questi eventi vengono generati dal Microsoft-Windows-DotNETRuntime
provider sotto la AssemblyLoader
parola chiave (0x4
).
Prerequisiti
- .NET 5 SDK o versioni successive
- Strumento
dotnet-trace
Annotazioni
L'ambito delle capacità di dotnet-trace
va oltre la semplice raccolta di informazioni dettagliate sul caricamento di assembly. Per altre informazioni sull'utilizzo di dotnet-trace
, vedere dotnet-trace
.
Raccogliere una traccia con eventi di caricamento di assembly
È possibile usare dotnet-trace
per tracciare un processo esistente o per avviare un processo figlio e tracciarlo dall'avvio.
Tracciare un processo esistente
Per abilitare gli eventi di caricamento degli assembly nel runtime e raccoglierne una traccia, usare dotnet-trace
con il comando seguente:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id <pid>
Questo comando raccoglie una traccia del <pid>
specificato, abilitando gli eventi AssemblyLoader
nel provider Microsoft-Windows-DotNETRuntime
. Il risultato è un .nettrace
file.
Usare dotnet-trace per avviare un processo figlio e tracciarlo dall'avvio
A volte può essere utile raccogliere una traccia di un processo dall'avvio. Per le app che eseguono .NET 5 o versioni successive, è possibile usare dotnet-trace
per eseguire questa operazione.
Il comando seguente avvia hello.exe con arg1
e arg2
come argomenti della riga di comando e raccoglie una traccia dall'avvio del runtime:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 -- hello.exe arg1 arg2
È possibile interrompere la raccolta della traccia premendo INVIO o CTRL + C. Questo chiude anche hello.exe.
Annotazioni
- L'avvio hello.exe tramite
dotnet-trace
reindirizza l'input e l'output e non sarà possibile interagire con esso nella console per impostazione predefinita. Usare l'opzione--show-child-io
per interagire con il suostdin
estdout
. - Uscendo dallo strumento tramite CTRL+C si termina in modo sicuro sia lo strumento che il processo figlio.
- Se il processo figlio viene chiuso prima dello strumento, lo strumento viene chiuso e la traccia deve essere visualizzabile in modo sicuro.
Visualizzare una traccia
Il file di traccia raccolto può essere visualizzato in Windows usando la visualizzazione Eventi in PerfView. Tutti gli eventi di caricamento dell'assembly saranno preceduti da Microsoft-Windows-DotNETRuntime/AssemblyLoader
.
Esempio (in Windows)
In questo esempio viene usato l'esempio di punti di estensione per il caricamento dell'assembly. L'applicazione tenta di caricare un assembly MyLibrary
- un assembly a cui l'applicazione non fa riferimento e che quindi richiede una gestione in un punto di estensione per il caricamento dell'assembly affinché sia caricato con successo.
Raccogliere la traccia
Navigare nella directory con il campione scaricato. Compilare l'applicazione con:
dotnet build
Avviare l'applicazione con argomenti che indicano che deve essere sospesa, in attesa della pressione di un tasto. Al termine della ripresa, tenterà di caricare l'assembly nell'impostazione predefinita
AssemblyLoadContext
, senza la gestione necessaria per un caricamento riuscito. Passare alla directory di output ed eseguire:AssemblyLoading.exe /d default
Trova l'ID del processo dell'applicazione.
dotnet-trace ps
L'elenco mostrerà i processi disponibili. Per esempio:
35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
Collega
dotnet-trace
all'applicazione in esecuzione.dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
Nella finestra che esegue l'applicazione premere un tasto qualsiasi per consentire al programma di continuare. La traccia verrà interrotta automaticamente una volta che l'applicazione esce.
Visualizzare la traccia
Aprire la traccia raccolta in PerfView e aprire la visualizzazione Eventi. Filtrare l'elenco di eventi in base agli Microsoft-Windows-DotNETRuntime/AssemblyLoader
eventi.
Verranno visualizzati tutti i caricamenti di assembly che si sono verificati nell'applicazione dopo l'inizio del tracciamento. Per esaminare l'operazione di caricamento dell'assembly interessato in questo esempio - MyLibrary
, è possibile applicare ulteriori filtri.
Caricamenti di assembly
Filtrare la visualizzazione in base agli Start
eventi Stop
e Microsoft-Windows-DotNETRuntime/AssemblyLoader
usando l'elenco di eventi a sinistra. Aggiungere le colonne AssemblyName
, ActivityID
e Success
alla vista. Filtrare in base agli eventi contenenti MyLibrary
.
Nome evento | AssemblyName | ActivityID | Successo |
---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Falso |
Verrà visualizzata una Start
/Stop
coppia con Success=False
sull'evento Stop
, che indica che l'operazione di caricamento non è riuscita. Si noti che i due eventi hanno lo stesso ID attività. L'ID attività può essere utilizzato per filtrare tutti gli altri eventi del caricatore di assembly, lasciando solo quelli che corrispondono a questa operazione di caricamento.
Fallimento del tentativo di caricamento
Per una suddivisione più dettagliata dell'operazione di caricamento, filtrare la visualizzazione in base agli ResolutionAttempted
eventi in Microsoft-Windows-DotNETRuntime/AssemblyLoader
usando l'elenco di eventi a sinistra. Aggiungere le colonne AssemblyName
, Stage
e Result
alla vista. Filtra gli eventi con l'ID attività della coppia Start
/Stop
.
Nome evento | AssemblyName | Fase | Risultato |
---|---|---|---|
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 |
Gli eventi precedenti indicano che il caricatore di assembly ha tentato di risolvere l'assembly cercando nel contesto di carico corrente, eseguendo la logica di probe predefinita per gli assembly delle applicazioni gestite, richiamando i gestori per l'evento AssemblyLoadContext.Resolving e richiamando i gestori per l'evento AppDomain.AssemblyResolve. Per tutte queste fasi, l'assemblaggio non è stato trovato.
Punti di estensione
Per vedere quali punti di estensione sono stati richiamati, filtra la visualizzazione agli elementi AssemblyLoadContextResolvingHandlerInvoked
e AppDomainAssemblyResolveHandlerInvoked
sotto Microsoft-Windows-DotNETRuntime/AssemblyLoader
utilizzando l'elenco degli eventi a sinistra. Aggiungere le colonne AssemblyName
e HandlerName
alla vista. Filtra gli eventi con l'ID attività della coppia Start
/Stop
.
Nome evento | AssemblyName | HandlerName |
---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAppDomainAssemblyResolve |
Gli eventi precedenti indicano che è stato richiamato un gestore denominato OnAssemblyLoadContextResolving
per l'evento AssemblyLoadContext.Resolving e che è stato richiamato un gestore denominato OnAppDomainAssemblyResolve
per l'evento AppDomain.AssemblyResolve .
Raccogliere un'altra traccia
Eseguire l'applicazione con argomenti in modo che il gestore dell'evento AssemblyLoadContext.Resolving caricherà l'assembly MyLibrary
.
AssemblyLoading /d default alc-resolving
Raccogliere e aprire un altro .nettrace
file usando i passaggi precedenti.
Filtrare nuovamente sugli eventi Start
e Stop
per MyLibrary
. Dovresti vedere una coppia Start
/Stop
con un'altra Start
/Stop
in mezzo. L'operazione di caricamento interno rappresenta il carico attivato dal gestore per AssemblyLoadContext.Resolving quando ha chiamato AssemblyLoadContext.LoadFromAssemblyPath. Questa volta, dovresti vedere Success=True
sull'evento Stop
, indicando che l'operazione di caricamento è riuscita. Il ResultAssemblyPath
campo mostra il percorso dell'assembly risultante.
Nome evento | AssemblyName | ActivityID | Successo | 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/ | Vero | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Vero | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
È quindi possibile esaminare gli ResolutionAttempted
eventi con l'ID attività dal carico esterno per determinare il passaggio in cui l'assembly è stato risolto correttamente. Questa volta, gli eventi mostreranno che la AssemblyLoadContextResolvingEvent
fase ha avuto esito positivo. Il ResultAssemblyPath
campo mostra il percorso dell'assembly risultante.
Nome evento | AssemblyName | Fase | Risultato | 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 |
Guardando gli eventi AssemblyLoadContextResolvingHandlerInvoked
, si mostrerà che il gestore denominato OnAssemblyLoadContextResolving
è stato richiamato. Il ResultAssemblyPath
campo mostra il percorso dell'assembly restituito dal gestore.
Nome evento | AssemblyName | HandlerName | ResultAssemblyPath |
---|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Si noti che non esiste più un ResolutionAttempted
evento con la AppDomainAssemblyResolveEvent
fase o gli AppDomainAssemblyResolveHandlerInvoked
eventi, perché l'assembly è stato caricato correttamente prima di raggiungere il passaggio dell'algoritmo di caricamento che genera l'evento AppDomain.AssemblyResolve .