Share via


Recopilación de información detallada de carga de ensamblados

A partir de .NET 5, el entorno de ejecución puede emitir eventos a través de EventPipe con información detallada sobre la carga de ensamblados administrados como ayuda para diagnosticar problemas en la carga de ensamblados. El proveedor Microsoft-Windows-DotNETRuntime emite estos eventos bajo la palabra clave AssemblyLoader (0x4).

Requisitos previos

Nota:

El ámbito de las funcionalidades de dotnet-trace es mayor que la recopilación de información detallada de carga de ensamblados. Para más información sobre el uso de dotnet-trace, consulte dotnet-trace.

Recopilación de un seguimiento con eventos de carga de ensamblados

Puede usar dotnet-trace para hacer un seguimiento de un proceso existente o para iniciar un proceso secundario y hacer un seguimiento desde el inicio.

Seguimiento de un proceso existente

Para habilitar los eventos de carga de ensamblados en el entorno de ejecución y recopilar un seguimiento de ellos, use dotnet-trace con el siguiente comando:

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

Este comando recopila un seguimiento del <pid> especificado, lo que habilita los eventos AssemblyLoader en el proveedor Microsoft-Windows-DotNETRuntime. El resultado es un archivo .nettrace.

Uso de dotnet-trace para iniciar un proceso secundario y hacer un seguimiento desde el inicio

A veces puede resultar útil recopilar un seguimiento de un proceso desde su inicio. Para las aplicaciones que ejecutan .NET 5 o versiones posteriores, puede usar dotnet-trace para esto.

El comando siguiente inicia hello.exe con arg1 y arg2 como argumentos de la línea de comandos, y recopila un seguimiento de su inicio en tiempo de ejecución:

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

Para detener la recopilación del seguimiento, presione ENTRAR o CTRL + C. Esto también cierra hello.exe.

Nota

  • El inicio de hello.exe mediante dotnet-trace redirige su entrada y salida, y usted no podrá interactuar con el archivo en la consola de manera predeterminada. Use el modificador --show-child-io para interactuar con su stdin y stdout.
  • La salida de la herramienta por medio de CTRL+C o SIGTERM finaliza de manera segura la herramienta y el proceso secundario.
  • Si el proceso secundario termina antes que la herramienta, la herramienta también se cierra y el seguimiento se debería poder ver de forma segura.

Visualización de un seguimiento

El archivo de seguimiento recopilado se puede ver en Windows mediante la vista Eventos en PerfView. Todos los eventos de carga de ensamblados tendrán como prefijo Microsoft-Windows-DotNETRuntime/AssemblyLoader.

Ejemplo (en Windows)

En este ejemplo se usa el ejemplo de puntos de extensión de la carga de ensamblados. La aplicación intenta cargar un ensamblado MyLibrary; un ensamblado al que no hace referencia la aplicación y, por tanto, requiere el control en un punto de extensión de carga de ensamblados para que se cargue correctamente.

Recopilación del seguimiento

  1. Navegue hasta el directorio con el ejemplo descargado. Compile la aplicación:

    dotnet build
    
  2. Inicie la aplicación con argumentos que indiquen que debe hacer una pausa, a la espera de que se presione una tecla. Al reanudar la operación, intentará cargar el ensamblado en el AssemblyLoadContext predeterminado, sin el control necesario para una carga correcta. Navegue hasta el directorio de salida y ejecute:

    AssemblyLoading.exe /d default
    
  3. Busque el identificador de proceso de la aplicación.

    dotnet-trace ps
    

    En la salida se enumerarán los procesos disponibles. Por ejemplo:

    35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
    
  4. Adjunte dotnet-trace a la aplicación en ejecución.

    dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
    
  5. En la ventana que ejecuta la aplicación, presione cualquier tecla para dejar que el programa continúe. El seguimiento se detendrá automáticamente una vez que se cierre la aplicación.

Visualización del seguimiento

Abra el seguimiento recopilado en PerfView y abra la vista Eventos. Filtre la lista de eventos para eventos Microsoft-Windows-DotNETRuntime/AssemblyLoader.

PerfView assembly loader filter image

Se mostrarán todas las cargas de ensamblado que se produjeron en la aplicación después del inicio del seguimiento. Para inspeccionar la operación de carga para el ensamblado de interés para este ejemplo (MyLibrary), podemos seguir filtrando.

Cargas de ensamblado

Filtre la vista por los eventos Start y Stop en Microsoft-Windows-DotNETRuntime/AssemblyLoader con la lista de eventos de la izquierda. Agregue las columnas AssemblyName, ActivityID y Success a la vista. Filtre los eventos que contienen MyLibrary.

PerfView Start and Stop events image

Nombre del evento AssemblyName Identificador de actividad Correcto
AssemblyLoader/Start MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ False

Debería ver un par Start/Stop con Success=False en el evento Stop, lo cual indica que se ha producido un error en la operación de carga. Tenga en cuenta que los dos eventos tienen el mismo identificador de actividad. El identificador de actividad se puede usar para filtrar todos los demás eventos del cargador de ensamblados a solo los que corresponden a esta operación de carga.

Desglose del intento de carga

Para obtener un desglose más detallado de la operación de carga, filtre la vista por los eventos ResolutionAttempted bajo Microsoft-Windows-DotNETRuntime/AssemblyLoader mediante la lista de eventos de la izquierda. Agregue las columnas AssemblyName, Stage y Result a la vista. Filtre los eventos con el identificador de actividad del par Start/Stop.

PerfView ResolutionAttempted events image

Nombre del evento AssemblyName Fase 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

Los eventos anteriores indican que el cargador de ensamblados intentó resolver el ensamblado examinando el contexto de carga actual, ejecutando la lógica de sondeo predeterminada para los ensamblados de aplicación administrados, invocando controladores para el evento AssemblyLoadContext.Resolving e invocando controladores para AppDomain.AssemblyResolve. En todos estos pasos, no se encontró el ensamblado.

Puntos de extensión

Para ver los puntos de extensión que se invocaron, filtre la vista a AssemblyLoadContextResolvingHandlerInvoked y AppDomainAssemblyResolveHandlerInvoked en Microsoft-Windows-DotNETRuntime/AssemblyLoader mediante la lista de eventos de la izquierda. Agregue las columnas AssemblyName y HandlerName a la vista. Filtre los eventos con el identificador de actividad del par Start/Stop.

PerfView extension point events image

Nombre del evento AssemblyName HandlerName
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAppDomainAssemblyResolve

Los eventos anteriores indican que se invocó un controlador con el nombre OnAssemblyLoadContextResolving para el evento AssemblyLoadContext.Resolving y que se invocó un controlador denominado OnAppDomainAssemblyResolve para el evento AppDomain.AssemblyResolve.

Recopilación de otro seguimiento

Ejecute la aplicación con argumentos de modo que su controlador para el evento AssemblyLoadContext.Resolving cargue el ensamblado MyLibrary.

AssemblyLoading /d default alc-resolving

Recopile y abra otro archivo .nettrace con los pasos anteriores.

Filtre de nuevo a los eventos Start y Stop de MyLibrary. Debería ver un par Start/Stop con otro Start/Stop entre ellos. La operación de carga interna representa la carga desencadenada por el controlador para AssemblyLoadContext.Resolving cuando llamó a AssemblyLoadContext.LoadFromAssemblyPath. Esta vez, debería ver Success=True en el evento Stop, lo cual indica que la operación de carga se realizó correctamente. En el campo ResultAssemblyPath se muestra la ruta de acceso del ensamblado resultante.

PerfView successful Start and Stop events image

Nombre del evento AssemblyName Identificador de actividad Correcto 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/ True C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ True C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

A continuación, podemos examinar los eventos ResolutionAttempted con el identificador de actividad de la carga externa para determinar el paso en el que el ensamblado se resolvió correctamente. Esta vez, los eventos mostrarán que la fase AssemblyLoadContextResolvingEvent se ha realizado correctamente. En el campo ResultAssemblyPath se muestra la ruta de acceso del ensamblado resultante.

PerfView successful ResolutionAttempted events image

Nombre del evento AssemblyName Fase 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

Al fijarse en los eventos AssemblyLoadContextResolvingHandlerInvoked, verá que se invocó el controlador denominado OnAssemblyLoadContextResolving. El campo ResultAssemblyPath muestra la ruta de acceso del ensamblado devuelto por el controlador.

PerfView successful extension point events image

Nombre del evento AssemblyName HandlerName ResultAssemblyPath
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

Tenga en cuenta que ya no hay un evento ResolutionAttempted con la fase AppDomainAssemblyResolveEvent ni eventos AppDomainAssemblyResolveHandlerInvoked, ya que el ensamblado se cargó correctamente antes de alcanzar el paso del algoritmo de carga que genera el evento AppDomain.AssemblyResolve.

Vea también