Partager via


Collecter des informations détaillées sur le chargement des assemblies

À compter de .NET 5, le runtime peut émettre des événements avec EventPipe des informations détaillées sur le chargement d’assembly managé pour faciliter le diagnostic des problèmes de chargement d’assembly. Ces événements sont émis par le Microsoft-Windows-DotNETRuntime fournisseur sous le AssemblyLoader mot clé (0x4).

Conditions préalables

Remarque

L’étendue des dotnet-trace fonctionnalités est supérieure à la collecte d’informations détaillées sur le chargement d’assembly. Pour plus d’informations sur l’utilisation de dotnet-trace, consultez dotnet-trace.

Collecter une trace avec des événements de chargement d’assembly

Vous pouvez utiliser dotnet-trace pour tracer un processus existant ou lancer un processus enfant et le suivre à partir du démarrage.

Suivre un processus existant

Pour activer le chargement des événements d’assembly dans le runtime et collecter une trace d’entre eux, utilisez dotnet-trace la commande suivante :

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

Cette commande collecte une trace de l’élément spécifié <pid>, en activant les AssemblyLoader événements dans le Microsoft-Windows-DotNETRuntime fournisseur. Le résultat est un .nettrace fichier.

Utiliser dotnet-trace pour lancer un processus enfant et le suivre à partir du démarrage

Parfois, il peut être utile de collecter une trace d’un processus à partir de son démarrage. Pour les applications exécutant .NET 5 ou une version ultérieure, vous pouvez l’utiliser dotnet-trace pour ce faire.

La commande suivante lance hello.exe avec arg1 et arg2 en tant qu’arguments de ligne de commande et collecte une trace à partir de son démarrage d’exécution :

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

Vous pouvez arrêter de collecter la trace en appuyant sur Entrée ou Ctrl + C. Cela ferme également hello.exe.

Remarque

  • Lancer hello.exe via dotnet-trace redirige ses entrées et sorties, et vous ne pourrez pas interagir avec elle sur la console par défaut. Utilisez le --show-child-io commutateur pour interagir avec son stdin et stdout.
  • Quitter l’outil via Ctrl+C ou SIGTERM mettre fin en toute sécurité à l’outil et au processus enfant.
  • Si le processus enfant se termine avant l’outil, l’outil se ferme également et la trace doit être visible en toute sécurité.

Afficher une trace

Le fichier de trace collecté peut être affiché sur Windows à l’aide de l’affichage Événements dans PerfView. Tous les événements de chargement d’assembly sont préfixés par Microsoft-Windows-DotNETRuntime/AssemblyLoader.

Exemple (sur Windows)

Cet exemple utilise l’exemple de points d’extension de chargement d’assembly. L’application tente de charger un assembly , un assembly MyLibrary qui n’est pas référencé par l’application et nécessite donc une gestion dans un point d’extension de chargement d’assembly pour être correctement chargé.

Collecter la trace

  1. Accédez au répertoire avec l’exemple téléchargé. Générez l’application avec :

    dotnet build
    
  2. Lancez l’application avec des arguments indiquant qu’elle doit s’interrompre, en attendant une touche d’appui. Lors de la reprise, il tente de charger l’assembly par défaut AssemblyLoadContext , sans la gestion nécessaire pour une charge réussie. Accédez au répertoire de sortie et exécutez :

    AssemblyLoading.exe /d default
    
  3. Recherchez l’ID de processus de l’application.

    dotnet-trace ps
    

    La sortie répertorie les processus disponibles. Par exemple:

    35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
    
  4. Attachez-vous dotnet-trace à l’application en cours d’exécution.

    dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
    
  5. Dans la fenêtre exécutant l’application, appuyez sur n’importe quelle touche pour permettre au programme de continuer. Le suivi s’arrête automatiquement une fois l’application terminée.

Afficher la trace

Ouvrez la trace collectée dans PerfView et ouvrez l’affichage Événements. Filtrez la liste des événements sur Microsoft-Windows-DotNETRuntime/AssemblyLoader les événements.

Image de filtre du chargeur d’assembly PerfView

Toutes les charges d’assembly qui se sont produites dans l’application après le suivi sont affichées. Pour inspecter l’opération de chargement de l’assembly d’intérêt pour cet exemple , MyLibrarynous pouvons effectuer un filtrage supplémentaire.

Chargements d’assemblys

Filtrez l’affichage sur les Start événements et Stop sous Microsoft-Windows-DotNETRuntime/AssemblyLoader utilisant la liste des événements sur la gauche. Ajoutez les colonnes AssemblyName, ActivityIDet Success à la vue. Filtrez les événements contenant MyLibrary.

Image d’événements De démarrage et d’arrêt PerfView

Nom de l'événement AssemblyName ActivityID Succès
AssemblyLoader/Start MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ Faux

Vous devez voir une Start/Stop paire avec Success=False l’événement Stop , indiquant que l’opération de chargement a échoué. Notez que les deux événements ont le même ID d’activité. L’ID d’activité peut être utilisé pour filtrer tous les autres événements de chargeur d’assembly sur ceux correspondant à cette opération de chargement.

Répartition de la tentative de chargement

Pour obtenir une répartition plus détaillée de l’opération de chargement, filtrez l’affichage sur les ResolutionAttempted événements sous Microsoft-Windows-DotNETRuntime/AssemblyLoader utilisant la liste des événements à gauche. Ajoutez les colonnes AssemblyName, Stageet Result à la vue. Filtrez les événements avec l’ID d’activité de la Start/Stop paire.

Image d’événements PerfView ResolutionAttempted

Nom de l'événement AssemblyName Étape Résultat
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

Les événements ci-dessus indiquent que le chargeur d’assembly a tenté de résoudre l’assembly en recherchant dans le contexte de charge actuel, en exécutant la logique de détection par défaut pour les assemblys d’application managée, en appelant des gestionnaires pour l’événement AssemblyLoadContext.Resolving et en appelant des gestionnaires pour le AppDomain.AssemblyResolve. Pour toutes ces étapes, l’assembly n’a pas été trouvé.

Points d’extension

Pour voir quels points d’extension ont été appelés, filtrez l’affichage vers l’affichage AssemblyLoadContextResolvingHandlerInvoked et AppDomainAssemblyResolveHandlerInvoked sous Microsoft-Windows-DotNETRuntime/AssemblyLoader à l’aide de la liste des événements à gauche. Ajoutez les colonnes AssemblyName et HandlerName à la vue. Filtrez les événements avec l’ID d’activité de la Start/Stop paire.

Image d’événements de point d’extension PerfView

Nom de l'événement AssemblyName HandlerName
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAppDomainAssemblyResolve

Les événements ci-dessus indiquent qu’un gestionnaire nommé OnAssemblyLoadContextResolving a été appelé pour l’événement AssemblyLoadContext.Resolving et qu’un gestionnaire nommé OnAppDomainAssemblyResolve a été appelé pour l’événement AppDomain.AssemblyResolve .

Collecter une autre trace

Exécutez l’application avec des arguments de sorte que son gestionnaire pour l’événement AssemblyLoadContext.Resolving charge l’assembly MyLibrary .

AssemblyLoading /d default alc-resolving

Collectez et ouvrez un autre .nettrace fichier en suivant les étapes ci-dessus.

Filtrez à nouveau sur les événements et Stop les Start événementsMyLibrary. Vous devriez voir une Start/Stop paire avec une autre Start/Stop entre eux. L’opération de charge interne représente la charge déclenchée par le gestionnaire pour le moment où AssemblyLoadContext.Resolving elle a appelé AssemblyLoadContext.LoadFromAssemblyPath. Cette fois, vous devez voir Success=True sur l’événement Stop , indiquant que l’opération de chargement a réussi. Le ResultAssemblyPath champ affiche le chemin d’accès de l’assembly résultant.

Image d’événements Démarrer et Arrêter réussies perfView

Nom de l'événement AssemblyName ActivityID Succès 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/ Vrai C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ Vrai C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

Nous pouvons ensuite examiner les ResolutionAttempted événements avec l’ID d’activité de la charge externe pour déterminer l’étape à laquelle l’assembly a été résolu avec succès. Cette fois, les événements montrent que la AssemblyLoadContextResolvingEvent phase a réussi. Le ResultAssemblyPath champ affiche le chemin d’accès de l’assembly résultant.

Image d’événements RésolutionAttempted réussie perfView

Nom de l'événement AssemblyName Étape Résultat 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

L’affichage AssemblyLoadContextResolvingHandlerInvoked des événements montre que le gestionnaire nommé OnAssemblyLoadContextResolving a été appelé. Le ResultAssemblyPath champ affiche le chemin d’accès de l’assembly retourné par le gestionnaire.

Image d’événements de point d’extension perfView réussies

Nom de l'événement AssemblyName HandlerName ResultAssemblyPath
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

Notez qu’il n’existe plus d’événement ResolutionAttempted avec l’étape AppDomainAssemblyResolveEvent ou tout AppDomainAssemblyResolveHandlerInvoked événement, car l’assembly a été correctement chargé avant d’atteindre l’étape de l’algorithme de chargement qui déclenche l’événement AppDomain.AssemblyResolve .

Voir aussi