Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Do .NET 5 em diante, o runtime pode emitir eventos por meio de EventPipe com informações detalhadas sobre o carregamento de assembly gerenciado para ajudar no diagnóstico de problemas de carregamento de assembly. Esses eventos são emitidos pelo Microsoft-Windows-DotNETRuntime provedor sob a AssemblyLoader palavra-chave (0x4).
Pré-requisitos
- SDK do .NET 5 ou versões posteriores
- Ferramenta
dotnet-trace
Observação
O escopo de funcionalidades de dotnet-trace é maior do que coletar informações detalhadas de carregamento de assembly. Para obter mais informações sobre o uso de dotnet-trace, consulte dotnet-trace.
Coletar um rastreamento com eventos de carregamento de assembly
Você pode usar dotnet-trace para rastrear um processo existente ou iniciar um processo filho e rastreá-lo da inicialização.
Rastrear um processo existente
Para habilitar eventos de carregamento de assembly em tempo de execução e coletar um rastreamento deles, use dotnet-trace com o seguinte comando:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id <pid>
Esse comando coleta um rastreamento do <pid> especificado habilitando os eventos de AssemblyLoader no provedor Microsoft-Windows-DotNETRuntime. O resultado é um .nettrace arquivo.
Usar o dotnet-trace para iniciar um processo filho e rastreá-lo desde a inicialização
Às vezes, pode ser útil coletar o rastreamento de um processo desde a inicialização. Para aplicativos que executam o .NET 5 ou posterior, você pode usar dotnet-trace para fazer isso.
O seguinte comando inicia hello.exe com arg1 e arg2 como argumentos de linha de comando e coleta um rastreamento desde a inicialização em tempo de execução:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 -- hello.exe arg1 arg2
Você pode parar de coletar o rastreamento pressionando Enter ou Ctrl + C. Isso também fecha o hello.exe.
Observação
- O lançamento de hello.exe via
dotnet-traceredireciona sua entrada e saída, e você não poderá interagir com ele no console por padrão. Use a opção--show-child-iopara interagir com as respectivasstdinestdout. - O encerramento da ferramenta por meio de Ctrl+C ou
SIGTERMencerra com segurança a ferramenta e o processo filho. - Se o processo filho for encerrado antes da ferramenta, a ferramenta também será encerrada e o rastreamento será exibido com segurança.
Exibir um rastreamento
O arquivo de rastreamento coletado pode ser exibido no Windows usando a exibição Eventos no PerfView. Todos os eventos de carregamento do assembly serão prefixados com Microsoft-Windows-DotNETRuntime/AssemblyLoader.
Exemplo (no Windows)
Este exemplo usa a amostra de pontos de extensão de carregamento de assembly. O aplicativo tenta carregar um assembly MyLibrary – Um assembly que não é referenciado pelo aplicativo e, portanto, requer o processamento de um ponto de extensão de carregamento de assembly para que ele seja carregado com êxito.
Coletar o rastreamento
Navegue até o diretório com o exemplo baixado. Crie o aplicativo com:
dotnet buildInicie o aplicativo com argumentos que indicam que ele deve pausar, aguardando uma tecla ser pressionada. Na retomada, ele tentará carregar o assembly no padrão
AssemblyLoadContext– Sem o processamento necessário para o sucesso do carregamento. Navegue até o diretório de saída e execute:AssemblyLoading.exe /d defaultEncontre o ID do processo do aplicativo.
dotnet-trace psA saída listará os processos disponíveis. Por exemplo:
35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exeAnexe
dotnet-traceao aplicativo em execução.dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832Na janela que executa o aplicativo, pressione qualquer tecla para permitir que o programa continue. O rastreamento será interrompido automaticamente quando o aplicativo for encerrado.
Exibir o rastreamento
Abra o rastreamento coletado no PerfView e abra o modo de exibição Eventos. Filtre a lista de eventos para eventos de Microsoft-Windows-DotNETRuntime/AssemblyLoader.
Todos os carregamentos de assembly que ocorreram no aplicativo após o rastreamento iniciado serão mostrados. Para inspecionar a operação de carregamento do assembly deste exemplo, MyLibrary, podemos aplicar mais filtragens.
Carregamentos de assembly
Filtre a exibição para os eventos Start e Stop sob Microsoft-Windows-DotNETRuntime/AssemblyLoader usando a lista de eventos à esquerda. Adicione as colunas AssemblyName, ActivityID e Success à exibição. Filtrar eventos que contêm MyLibrary.
| Nome do evento | AssemblyName | IdentificadorDaAtividade | Êxito |
|---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Falso |
Você verá um par de Start/Stop com Success=False no evento Stop, indicando que a operação de carregamento falhou. Observe que os dois eventos têm a mesma ID de atividade. A ID da atividade pode ser usada para filtrar todos os outros eventos do carregador de assembly apenas aos correspondentes a essa operação de carregamento.
Descrição detalhada da tentativa de carregamento
Para obter um detalhamento mais profundo da operação de carga, filtre a exibição para os ResolutionAttempted eventos sob Microsoft-Windows-DotNETRuntime/AssemblyLoader usando a lista de eventos à esquerda. Adicione as colunas AssemblyName, Stage e Result à exibição. Filtre eventos com a ID da atividade do par Start/Stop.
| Nome do evento | AssemblyName | Etapa | Resultado |
|---|---|---|---|
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 |
Os eventos acima indicam que o carregador de assembly tentou resolver o assembly examinando o contexto de carregamento atual, executando a lógica de investigação padrão para assemblies de aplicativos gerenciados, invocando manipuladores para o evento AssemblyLoadContext.Resolving e invocando manipuladores para o AppDomain.AssemblyResolve. Para todas essas etapas, o assembly não foi encontrado.
Pontos de extensão
Para ver quais pontos de extensão foram invocados, filtre a exibição em AssemblyLoadContextResolvingHandlerInvoked e AppDomainAssemblyResolveHandlerInvoked sob Microsoft-Windows-DotNETRuntime/AssemblyLoader usando a lista de eventos à esquerda. Adicione as colunas AssemblyName e HandlerName à visualização. Filtre eventos com a ID da atividade do par Start/Stop.
| Nome do evento | AssemblyName | HandlerName |
|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAppDomainAssemblyResolve |
Os eventos acima indicam que um manipulador nomeado OnAssemblyLoadContextResolving foi invocado para o AssemblyLoadContext.Resolving evento e um manipulador nomeado OnAppDomainAssemblyResolve foi invocado para o AppDomain.AssemblyResolve evento.
Coletar outro rastreamento
Execute o aplicativo com argumentos de modo que o manipulador do evento AssemblyLoadContext.Resolving carregue o conjunto de componentes MyLibrary.
AssemblyLoading /d default alc-resolving
Colete e abra outro .nettrace arquivo usando as etapas acima.
Filtre apenas os eventos Start e Stop para MyLibrary novamente. Você verá um par Start/Stop com outro Start/Stop entre eles. A operação interna de carregamento representa o carregamento disparado pelo manipulador para AssemblyLoadContext.Resolving quando ele chamou AssemblyLoadContext.LoadFromAssemblyPath. Desta vez, você deverá ver Success=True no Stop evento, indicando que a operação de carga foi bem-sucedida. O ResultAssemblyPath campo mostra o caminho da montagem resultante.
| Nome do evento | AssemblyName | IdentificadorDaAtividade | Êxito | 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/ | Verdade | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Verdade | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Depois, podemos examinar os eventos ResolutionAttempted com a ID da atividade do carregamento externo para determinar a etapa na qual o assembly foi resolvido com êxito. Desta vez, os eventos mostrarão que a fase AssemblyLoadContextResolvingEvent foi bem sucedida. O ResultAssemblyPath campo mostra o caminho da montagem resultante.
| Nome do evento | AssemblyName | Etapa | Resultado | 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 |
Ao examinar os eventos AssemblyLoadContextResolvingHandlerInvoked, veja que o manipulador chamado OnAssemblyLoadContextResolving foi invocado. O campo ResultAssemblyPath mostra o caminho do assembly retornado pelo manipulador.
| Nome do evento | AssemblyName | HandlerName | ResultAssemblyPath |
|---|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Observe que não há mais um evento ResolutionAttempted com a fase AppDomainAssemblyResolveEvent nem eventos AppDomainAssemblyResolveHandlerInvoked, pois o assembly foi carregado com êxito antes de chegar à fase do algoritmo de carregamento que gera o evento AppDomain.AssemblyResolve.