Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
À partir de .NET 5, le runtime peut émettre des événements via EventPipe avec des informations détaillées sur le chargement des assemblages managés pour faciliter le diagnostic des problèmes liés au chargement des assemblages. Ces événements sont émis par le Microsoft-Windows-DotNETRuntime fournisseur sous le AssemblyLoader mot clé (0x4).
Conditions préalables
- Sdk .NET 5 ou versions ultérieures
- Outil
dotnet-trace
Remarque
L’étendue des fonctionnalités dotnet-trace 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’assemblage en runtime et collecter une trace d’entre eux, utilisez dotnet-trace avec 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 événements AssemblyLoader dans le fournisseur Microsoft-Windows-DotNETRuntime. 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-traceredirige ses entrées et sorties, et vous ne pourrez pas interagir avec elle sur la console par défaut. Utilisez le commutateur--show-child-iopour interagir avecstdinetstdout. - Quitter l’outil via Ctrl+C ou
SIGTERMmet 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 MyLibrary, qui n’est pas référencé par l’application et nécessite donc d'être géré dans un point d’extension de chargement d’assembly pour être chargé avec succès.
Collecter les traces
Accédez au répertoire avec l’exemple téléchargé. Générez l’application avec :
dotnet buildLancez l’application avec des arguments pour indiquer qu'elle doit se mettre en pause, en attendant l’appui sur une touche. Lors de la reprise du processus, il tente de charger l’assembly dans
AssemblyLoadContextpar défaut, sans la gestion nécessaire pour un chargement réussi. Accédez au répertoire de sortie et exécutez :AssemblyLoading.exe /d defaultRecherchez l’ID de processus de l’application.
dotnet-trace psLa sortie répertorie les processus disponibles. Par exemple:
35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exeAttachez
dotnet-traceà l'application en cours d'exécution.dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832Dans 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 les événements Microsoft-Windows-DotNETRuntime/AssemblyLoader.
Toutes les charges de l'assemblage qui se sont produites après le début du traçage dans l’application seront affichées. Pour inspecter l'opération de chargement de l'assembly concerné pour cet exemple—MyLibrary—nous pouvons effectuer un filtrage supplémentaire.
Chargements d’assemblys
Filtrez l'affichage pour les événements Start et Stop sous Microsoft-Windows-DotNETRuntime/AssemblyLoader en utilisant la liste des événements sur la gauche. Ajoutez les colonnes AssemblyName, ActivityIDet Success à la vue. Filtrez les événements contenant MyLibrary.
| Nom de l'événement | NomDeL'Assemblée | ActivityID | Succès |
|---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Faux |
Vous devriez voir une paire Start/Stop avec Success=False sur 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 pour n'afficher que 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.
| Nom de l'événement | NomDeL'Assemblée | É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'assemblage n'a pas été trouvé.
Points d’extension
Pour voir quels points d’extension ont été appelés, filtrez l’affichage sur 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.
| Nom de l'événement | NomDeL'Assemblée | 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 les événements Start et Stop pour MyLibrary. 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 de AssemblyLoadContext.Resolving lorsqu'il 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 champ ResultAssemblyPath affiche le chemin d’accès de l’assembly résultant.
| Nom de l'événement | NomDeL'Assemblée | 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é provenant du chargement externe pour déterminer l’étape à laquelle l’assemblage a été résolue avec succès. Cette fois, les événements montrent que l’étape AssemblyLoadContextResolvingEvent a réussi. Le champ ResultAssemblyPath affiche le chemin d’accès de l’assembly résultant.
| Nom de l'événement | NomDeL'Assemblée | É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 |
En regardant les événements AssemblyLoadContextResolvingHandlerInvoked, on verra que le gestionnaire nommé OnAssemblyLoadContextResolving a été appelé. Le champ ResultAssemblyPath affiche le chemin d’accès de l’assembly retourné par le gestionnaire.
| Nom de l'événement | NomDeL'Assemblée | HandlerName | ResultAssemblyPath |
|---|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Veuillez noter qu'il n'y a plus d'événement ResolutionAttempted lié à l'étape AppDomainAssemblyResolveEvent ni aucun événement AppDomainAssemblyResolveHandlerInvoked, car l'assembly a été chargé avec succès avant d'atteindre l'étape de l'algorithme de chargement qui déclenche l'événement AppDomain.AssemblyResolve.