Partilhar via


Recolher informações detalhadas sobre o carregamento da montagem

A partir do .NET 5, o runtime pode emitir eventos através de EventPipe com informações detalhadas sobre o carregamento de assemblagem gerida para ajudar no diagnóstico de problemas de carregamento de assemblagem. Esses eventos são emitidos pelo Microsoft-Windows-DotNETRuntime provedor sob a AssemblyLoader palavra-chave (0x4).

Pré-requisitos

Observação

O alcance das dotnet-trace capacidades é maior do que a coleta de informações detalhadas sobre o carregamento de montagem. Para obter mais informações sobre o uso do dotnet-trace, consulte dotnet-trace.

Recolher um traço com eventos de carregamento de assemblagem

Você pode usar dotnet-trace para rastrear um processo existente ou para iniciar um processo filho e rastreá-lo desde a inicialização.

Rastrear um processo existente

Para ativar eventos de carregamento de assembly no runtime e recolher um registo deles, use dotnet-trace com o seguinte comando:

dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id <pid>

Este comando recolhe um rastreio do especificado <pid>, ativando AssemblyLoader eventos no fornecedor Microsoft-Windows-DotNETRuntime. O resultado é um .nettrace ficheiro.

Utilize o dotnet-trace para executar um processo filho e rastreá-lo desde o início.

Às vezes, pode ser útil coletar um traço de um processo de sua inicialização. Para aplicativos que executam o .NET 5 ou posterior, você pode usar dotnet-trace para fazer isso.

O comando a seguir inicia hello.exe com arg1 e arg2 como seus argumentos de linha de comando e coleta um rastreamento de sua inicialização em tempo de execução:

dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 -- hello.exe arg1 arg2

Você pode parar de recolher o rastreamento pressionando Enter ou Ctrl + C. Isso também fecha hello.exe.

Observação

  • Iniciar hello.exe via dotnet-trace redireciona sua entrada e saída, e você não poderá interagir com ele no console por padrão. Use o interruptor para interagir com --show-child-io, stdin e stdout.
  • Sair da ferramenta via Ctrl+C encerra com segurança tanto a ferramenta quanto o processo filho.
  • ** Se o processo filho terminar antes da ferramenta, a ferramenta também irá encerrar e o rastreamento poderá ser visualizado de forma segura.

Ver rastreamento

O arquivo de rastreamento coletado pode ser visualizado no Windows usando o modo de exibição Eventos no PerfView. Todos os eventos de carregamento de montagem serão prefixados com Microsoft-Windows-DotNETRuntime/AssemblyLoader.

Exemplo (em Windows)

Este exemplo usa o exemplo de pontos de extensão de carregamento de montagem. A aplicação tenta carregar uma assemblagem MyLibrary - uma assemblagem que não é referenciada pela aplicação e, portanto, requer manipulação num ponto de extensão de carregamento de assemblagem para ser carregada com êxito.

Recolher o vestígio

  1. Navegue até o diretório com o exemplo baixado. Crie o aplicativo com:

    dotnet build
    
  2. Inicie o aplicativo com argumentos indicando que ele deve pausar, aguardando um pressionamento de tecla. Ao retomar, ele tentará carregar a assemblagem no ambiente padrão AssemblyLoadContext - sem o tratamento necessário para uma carga bem-sucedida. Navegue até o diretório de saída e execute:

    AssemblyLoading.exe /d default
    
  3. Encontre o ID do processo do aplicativo.

    dotnet-trace ps
    

    A saída listará os processos disponíveis. Por exemplo:

    35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
    
  4. Anexe dotnet-trace ao aplicativo em execução.

    dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
    
  5. Na janela que executa o aplicativo, pressione qualquer tecla para permitir que o programa continue. O rastreamento será interrompido automaticamente assim que o aplicativo for encerrado.

Ver o traço

Abra o rastreamento coletado no PerfView e abra o modo de exibição Eventos. Filtre a lista de eventos para incluir apenas Microsoft-Windows-DotNETRuntime/AssemblyLoader eventos.

Imagem do filtro de carregador de assemblies PerfView

Todas as cargas de montagem que ocorreram no aplicativo após o início do rastreamento serão mostradas. Para inspecionar o processo de carga para a montagem em questão para este exemplo - MyLibrary, podemos aplicar alguns filtros adicionais.

Cargas de montagem

Filtre a visualizaçã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 à vista. Filtrar eventos que contenham MyLibrary.

Imagem dos eventos de início e término do PerfView

Nome do evento NomeDaAssembleia ID da atividade Sucesso
AssemblyLoader/Start MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ Falso

Você deve ver um Start/Stop par com Success=False no Stop evento, indicando que a operação de carregamento falhou. Observe que os dois eventos têm o mesmo ID de atividade. O ID da atividade pode ser usado para limitar todos os outros eventos do carregador de montagem apenas aos que correspondem a esta operação de carga.

Avaria da tentativa de carregamento

Para obter um detalhamento mais detalhado da operação de carga, filtre a exibição para os ResolutionAttempted eventos em Microsoft-Windows-DotNETRuntime/AssemblyLoader usando a lista de eventos à esquerda. Adicione as colunas AssemblyName, Stage, e Result à vista. Filtre eventos com o ID de atividade do par Start/Stop.

PerfView ResolutionImagem de eventos tentados

Nome do evento NomeDaAssembleia 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 assemblies tentou resolver o assembly procurando no contexto de carga atual, executando a lógica padrão de pesquisa para assemblies de aplicações geridas, invocando manipuladores para o evento AssemblyLoadContext.Resolving e para o evento AppDomain.AssemblyResolve. Em todas estas etapas, a montagem não foi encontrada.

Pontos de extensão

Para ver quais pontos de extensão foram invocados, filtre a exibição para AssemblyLoadContextResolvingHandlerInvoked e AppDomainAssemblyResolveHandlerInvoked sob Microsoft-Windows-DotNETRuntime/AssemblyLoader usando a lista de eventos à esquerda. Adicione as colunas AssemblyName e HandlerName à exibição. Filtre eventos com o ID de atividade do par Start/Stop.

Imagem de eventos de ponto de extensão PerfView

Nome do evento NomeDaAssembleia Nome do manipulador
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.

Recolher outro vestígio

Execute a aplicação com argumentos de modo a que o gestor para o AssemblyLoadContext.Resolving evento carregue a MyLibrary assemblagem.

AssemblyLoading /d default alc-resolving

Colete e abra outro .nettrace arquivo usando as etapas acima.

Filtre os eventos Start e Stop para MyLibrary novamente. Você deve ver um par de Start/Stop com outro Start/Stop entre eles. A operação de carga interna representa a carga acionada pelo manipulador para AssemblyLoadContext.Resolving quando ele chamou AssemblyLoadContext.LoadFromAssemblyPath. Desta vez, você deve ver Success=True no Stop evento, indicando que a operação de carregamento foi bem-sucedida. O ResultAssemblyPath campo mostra o caminho da montagem resultante.

Imagem de eventos Start e Stop bem-sucedidos do PerfView

Nome do evento NomeDaAssembleia ID da atividade Sucesso CaminhoDeMontagemDoResultado
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

Em seguida, podemos examinar os ResolutionAttempted eventos com o ID de atividade do carregamento externo para determinar a etapa em que o assembly foi resolvido com sucesso. Desta vez, os eventos mostrarão que a AssemblyLoadContextResolvingEvent etapa foi bem-sucedida. O ResultAssemblyPath campo mostra o caminho da montagem resultante.

Imagem de eventos PerfView ResolutionAttempted bem-sucedida

Nome do evento NomeDaAssembleia Etapa Resultado CaminhoDoResultadoDeCompilação
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

A observação dos AssemblyLoadContextResolvingHandlerInvoked eventos mostrará que o manipulador nomeado OnAssemblyLoadContextResolving foi invocado. O campo ResultAssemblyPath mostra o caminho do conjunto retornado pelo manipulador.

Imagem de eventos de ponto de extensão bem-sucedidos do PerfView

Nome do evento NomeDaAssembleia Nome do manipulador CaminhoDeMontagemDoResultado
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

Observe que não há mais um ResolutionAttempted evento com a AppDomainAssemblyResolveEvent etapa ou quaisquer AppDomainAssemblyResolveHandlerInvoked eventos, pois o assembly foi carregado com êxito antes de alcançar a etapa do algoritmo de carregamento que desencadeia o AppDomain.AssemblyResolve evento.

Ver também