Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Ab .NET 5 kann die Runtime Ereignisse über EventPipe mit detaillierten Informationen über das Laden von verwalteten Assemblys ausgeben, um bei der Diagnose von Problemen beim Laden von Assemblys zu helfen. Diese Ereignisse werden vom Microsoft-Windows-DotNETRuntime Anbieter unter dem AssemblyLoader Schlüsselwort (0x4) ausgegeben.
Voraussetzungen
- .NET 5 SDK oder höhere Versionen
-
dotnet-trace-Tool
Hinweis
Der Umfang der dotnet-trace-Funktionen ist größer als das Sammeln detaillierter Assemblyladeinformationen. Weitere Informationen zur Verwendung von dotnet-trace, finden Sie unter dotnet-trace.
Erfassen einer Ablaufverfolgung mit Assemblyladeereignissen
Sie können verwenden dotnet-trace , um einen vorhandenen Prozess nachzuverfolgen oder einen untergeordneten Prozess zu starten und ihn vom Start zu verfolgen.
Verfolgen eines vorhandenen Prozesses
Verwenden Sie dotnet-trace mit dem folgenden Befehl, um Assemblyladeereignisse in der Runtime zu aktivieren und eine Ablaufverfolgung zu erfassen:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id <pid>
Mit diesem Befehl wird eine Ablaufverfolgung der angegebenen <pid> erfasst, wodurch die AssemblyLoader-Ereignisse im Microsoft-Windows-DotNETRuntime-Anbieter aktiviert werden. Das Ergebnis ist eine .nettrace Datei.
Verwenden Sie dotnet-trace, um einen untergeordneten Prozess zu starten und ihn vom Start zu nachverfolgen.
Manchmal kann es nützlich sein, eine Ablaufverfolgung eines Prozesses vom Start zu erfassen. Für Apps mit .NET 5 oder höher können Sie dies verwenden dotnet-trace .
Mit dem folgenden Befehl wird hello.exe mit arg1 und arg2 als Befehlszeilenargumenten gestartet, und der Ablauf wird vom Start der Runtime verfolgt:
dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 -- hello.exe arg1 arg2
Sie können die Ablaufverfolgungssammlung beenden, indem Sie die Eingabetaste oder STRG + C drücken. Dadurch wird auch hello.exe geschlossen.
Hinweis
- Das Starten von hello.exe über
dotnet-traceumleitet seine Eingabe und Ausgabe, und Sie können standardmäßig nicht mit ihm auf der Konsole interagieren. Verwenden Sie den--show-child-ioSchalter, um mit seinemstdinundstdoutzu interagieren. - Wenn Sie das Tool über STRG+C oder
SIGTERMbeenden, wird sowohl das Tool als auch der untergeordnete Prozess sicher beendet. - Wenn der untergeordnete Prozess vor dem Tool beendet wird, wird das Tool ebenfalls beendet, und die Ablaufverfolgung sollte sicher angezeigt werden können.
Anzeigen einer Ablaufverfolgung
Die erfasste Protokolldatei kann unter Windows mithilfe der Ereignisansicht in PerfView angezeigt werden. Allen Assemblyladeereignissen wird Microsoft-Windows-DotNETRuntime/AssemblyLoader vorangestellt.
Beispiel (unter Windows)
Dies ist ein Beispiel mit Assemblylade-Erweiterungspunkten. Die Anwendung versucht, eine Assembly MyLibrary zu laden – eine Assembly, auf die nicht von der Anwendung verwiesen wird, und die daher in einem Assemblyladeerweiterungspunkt bearbeitet werden muss, um erfolgreich geladen zu werden.
Erfassen der Ablaufverfolgung
Navigieren Sie zum Verzeichnis mit dem heruntergeladenen Beispiel. Erstellen Sie die Anwendung mit:
dotnet buildStarten Sie die Anwendung mit Argumenten, die angeben, dass sie angehalten werden soll, und warten Sie auf ein Drücken einer Taste. Beim Fortsetzen wird versucht, die Assembly in der Standardeinstellung
AssemblyLoadContextzu laden – ohne die Handhabung, die für ein erfolgreiches Laden erforderlich ist. Navigieren Sie zum Ausgabeverzeichnis, und führen Sie Folgendes aus:AssemblyLoading.exe /d defaultSuchen Sie die Prozess-ID der Anwendung.
dotnet-trace psDie Ausgabe listet die verfügbaren Prozesse auf. Beispiel:
35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exeVerbinden Sie
dotnet-tracemit der laufenden Anwendung.dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832Drücken Sie im Fenster, in dem die Anwendung ausgeführt wird, eine beliebige Taste, damit das Programm fortgesetzt werden kann. Die Ablaufverfolgung wird automatisch beendet, nachdem die Anwendung beendet wurde.
Anzeigen der Ablaufverfolgung
Öffnen Sie die erfasste Ablaufverfolgung in PerfView, und öffnen Sie die Ansicht „Ereignisse“. Filtert die Ereignisliste auf Microsoft-Windows-DotNETRuntime/AssemblyLoader Ereignisse.
Alle Assemblyladungen, die nach dem Start der Ablaufverfolgung in der Anwendung aufgetreten sind, werden angezeigt. Um den Ladevorgang für die Assembly zu überprüfen, die für dieses Beispiel von Interesse ist – MyLibrary – können wir weitere Filterungen durchführen.
Assemblyladungen
Filtern Sie die Ansicht auf die Ereignisse Start und Stop unter Microsoft-Windows-DotNETRuntime/AssemblyLoader mithilfe der Ereignisliste auf der linken Seite. Fügen Sie die Spalten AssemblyName, ActivityIDund Success der Ansicht hinzu. Filtern Sie nach Ereignissen, die MyLibrary enthalten.
| Ereignisname | AssemblyName | Aktivitäts-ID | Erfolg |
|---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Falsch |
Es sollte ein Start/Stop-Paar mit Success=False für das Stop-Ereignis angezeigt werden, das angibt, dass beim Ladevorgang ein Fehler aufgetreten ist. Beachten Sie, dass die beiden Ereignisse dieselbe Aktivitäts-ID aufweisen. Die Aktivitäts-ID kann verwendet werden, um alle anderen Assemblyladeereignisse auf nur diejenigen zu filtern, die diesem Ladevorgang entsprechen.
Aufschlüsselung des Ladeversuchs
Für eine detailliertere Aufschlüsselung des Ladevorgangs filtern Sie die Ansicht mithilfe der Ereignisliste auf der linken Seite auf die ResolutionAttempted Ereignisse unter Microsoft-Windows-DotNETRuntime/AssemblyLoader. Fügen Sie die Spalten AssemblyName, Stageund Result der Ansicht hinzu. Filtern Sie nach Ereignissen mit der Aktivitäts-ID aus dem Start/Stop Paar.
| Ereignisname | AssemblyName | Etappe | Ergebnis |
|---|---|---|---|
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 |
Die obigen Ereignisse geben an, dass das Assemblyladeprogramm versucht hat, die Assembly aufzulösen, indem im aktuellen Ladekontext nachgeschaut wird, die Standard-Probinglogik für verwaltete Anwendungsassemblys ausgeführt wird, Handler für das AssemblyLoadContext.Resolving-Ereignis aufgerufen werden und Handler für das AppDomain.AssemblyResolve-Ereignis aufgerufen werden. In allen diesen Schritten wurde die Assembly nicht gefunden.
Erweiterungspunkte
Um zu sehen, welche Erweiterungspunkte aufgerufen wurden, filtern Sie die Ansicht zu AssemblyLoadContextResolvingHandlerInvoked und AppDomainAssemblyResolveHandlerInvoked unter Microsoft-Windows-DotNETRuntime/AssemblyLoader mithilfe der Ereignisliste auf der linken Seite. Fügen Sie die Spalten AssemblyName und HandlerName der Ansicht hinzu. Filtern Sie nach Ereignissen mit der Aktivitäts-ID aus dem Start/Stop Paar.
| Ereignisname | AssemblyName | HandlerName |
|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAppDomainAssemblyResolve |
Die obigen Ereignisse geben an, dass ein Handler mit dem Namen OnAssemblyLoadContextResolving für das AssemblyLoadContext.Resolving Ereignis aufgerufen wurde und ein Handler mit dem Namen OnAppDomainAssemblyResolve für das AppDomain.AssemblyResolve Ereignis aufgerufen wurde.
Erfassen einer anderen Ablaufverfolgung
Führen Sie die Anwendung mit Argumenten aus, sodass der Handler für das AssemblyLoadContext.Resolving Ereignis die MyLibrary Assembly lädt.
AssemblyLoading /d default alc-resolving
Sammeln und öffnen Sie eine andere .nettrace Datei mithilfe der oben beschriebenen Schritte.
Filtern Sie erneut die Start- und Stop-Ereignisse für MyLibrary. Du solltest ein Start/Stop-Paar sehen, mit einem anderen Start/Stop dazwischen. Der innere Ladevorgang stellt die Ladung dar, die vom Handler für AssemblyLoadContext.Resolving ausgelöst wurde, als AssemblyLoadContext.LoadFromAssemblyPath aufgerufen wurde. Dieses Mal sollten Sie Success=True im Stop Ereignis sehen, was darauf hinweist, dass der Ladevorgang erfolgreich war. Das ResultAssemblyPath Feld zeigt den Pfad der resultierenden Assembly an.
| Ereignisname | AssemblyName | Aktivitäts-ID | Erfolg | 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/ | Richtig | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Richtig | C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Wir können dann die ResolutionAttempted-Ereignisse mit der Aktivitäts-ID aus der äußeren Ladung betrachten, um den Schritt zu ermitteln, in dem die Assembly erfolgreich aufgelöst wurde. Dieses Mal zeigen die Ereignisse, dass die AssemblyLoadContextResolvingEvent Phase erfolgreich war. Das ResultAssemblyPath Feld zeigt den Pfad der resultierenden Assembly an.
| Ereignisname | AssemblyName | Etappe | Ergebnis | 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 |
Beim Betrachten von AssemblyLoadContextResolvingHandlerInvoked Ereignissen wird gezeigt, dass der genannte OnAssemblyLoadContextResolving handler aufgerufen wurde. Das ResultAssemblyPath Feld zeigt den Pfad der Assembly an, die vom Handler zurückgegeben wird.
| Ereignisname | AssemblyName | HandlerName | ResultAssemblyPath |
|---|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Beachten Sie, dass kein ResolutionAttempted-Ereignis mit der AppDomainAssemblyResolveEvent-Phase oder AppDomainAssemblyResolveHandlerInvoked-Ereignisse mehr vorhanden sind, da die Assembly erfolgreich geladen wurde, bevor der Schritt des Ladealgorithmus erreicht wurde, der das AppDomain.AssemblyResolve-Ereignis auslöst.