Dela via


Samla in detaljerad information om monteringsinläsning

Från och med .NET 5 kan runtime-miljön emittera händelser med EventPipe detaljerad information om assembly-inläsning för att hjälpa till att diagnostisera problem med assembly-inläsning. Dessa händelser genereras av providern Microsoft-Windows-DotNETRuntime under nyckelordet AssemblyLoader (0x4).

Förutsättningar

Anmärkning

Omfånget för dotnet-trace funktioner är större än att samla in detaljerad information om sammansättningsinläsning. Mer information om användningen av dotnet-tracefinns i dotnet-trace.

Samla in en spårning med sammansättningsinläsningshändelser

Du kan använda dotnet-trace för att spåra en befintlig process eller för att starta en underordnad process och spåra den från start.

Spåra en befintlig process

Om du vill aktivera händelser för sammansättningsinläsning i körningen och samla in en spårning av dem använder du dotnet-trace med följande kommando:

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

Det här kommandot samlar in en spårning av den angivna <pid>och aktiverar AssemblyLoader händelserna i providern Microsoft-Windows-DotNETRuntime . Resultatet är en .nettrace fil.

Använd dotnet-trace för att starta en underordnad process och spåra den från början

Ibland kan det vara användbart att samla in en spårning av en process från starten. För appar som kör .NET 5 eller senare kan du använda dotnet-trace för att göra detta.

Följande kommando startar hello.exe med arg1 och arg2 som kommandoradsargument och samlar in en spårning från körningsstarten:

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

Du kan sluta samla in spårningen genom att trycka på Retur eller Ctrl + C. Detta stänger även hello.exe.

Anmärkning

  • Om du startarhello.exe via dotnet-trace omdirigeras dess indata och utdata, och du kommer inte att kunna interagera med den i konsolen som standard. Använd brytaren --show-child-io för att interagera med stdin och stdout.
  • När verktyget avslutas via Ctrl+C eller SIGTERM avslutas på ett säkert sätt både verktyget och den underordnade processen.
  • Om den underordnade processen stängs innan verktyget, så stängs också verktyget och det ska vara säkert att se spårningen.

Visa en spårning

Den insamlade spårningsfilen kan visas i Windows med hjälp av händelsevyn i PerfView. Alla sammansättningsinläsningshändelser kommer att prefixeras med Microsoft-Windows-DotNETRuntime/AssemblyLoader.

Exempel (i Windows)

I det här exemplet används exemplet för sammansättningsinläsning av tilläggspunkter. Programmet försöker ladda ett assembly MyLibrary – ett assembly som inte är refererat av programmet och därför kräver hantering i en tilläggspunkt för assembly-inläsning för att kunna läsas in korrekt.

Samla in spår

  1. Navigera till katalogen med det nedladdade exemplet. Skapa programmet med:

    dotnet build
    
  2. Starta programmet med argument som anger att det ska pausas i väntan på en tangenttryckning. Vid återupptagandet kommer den att försöka läsa in sammansättningen i standardinställningen AssemblyLoadContext – utan den hantering som krävs för en lyckad belastning. Navigera till utdatakatalogen och kör:

    AssemblyLoading.exe /d default
    
  3. Hitta programmets process-ID.

    dotnet-trace ps
    

    Utdata visar de tillgängliga processerna. Till exempel:

    35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
    
  4. Koppla dotnet-trace till det program som körs.

    dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
    
  5. I fönstret som kör programmet trycker du på valfri tangent för att låta programmet fortsätta. Spårningen stoppas automatiskt när programmet avslutas.

Visa spårningen

Öppna den insamlade spårningen i PerfView och öppna vyn Händelser. Filtrera händelselistan till Microsoft-Windows-DotNETRuntime/AssemblyLoader händelser.

Filterbild för PerfView-sammansättningsinläsning

Alla sammansättningsbelastningar som inträffade i programmet efter att spårningen startats visas. Om vi vill granska belastningsoperationen för den intressanta sammansättningen i det här exemplet – MyLibrary, kan vi filtrera lite mer.

Monteringsbelastningar

Filtrera vyn för Start och Stop händelser under Microsoft-Windows-DotNETRuntime/AssemblyLoader med hjälp av händelselistan till vänster. Lägg till kolumnerna AssemblyName, ActivityIDoch Success i vyn. Filtrera efter händelser som innehåller MyLibrary.

Bild av start- och stopphändelser i PerfView

Händelsenamn Sammanställningsnamn Aktivitets-ID Framgång
AssemblyLoader/Start MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ Falsk

Du bör se ett Start/Stop par med Success=FalseStop händelsen, vilket indikerar att inläsningsåtgärden misslyckades. Observera att de två händelserna har samma aktivitets-ID. Aktivitets-ID:t kan användas för att filtrera alla andra sammansättningsinläsningshändelser till bara de som motsvarar den här belastningsåtgärden.

Analys av försök att läsa in

Om du vill ha en mer detaljerad uppdelning av belastningsåtgärden filtrerar du vyn efter händelsernaResolutionAttempted under Microsoft-Windows-DotNETRuntime/AssemblyLoader med hjälp av händelselistan till vänster. Lägg till kolumnerna AssemblyName, Stageoch Result i vyn. Filtrera efter händelser med aktivitets-ID:t från Start/Stop paret.

Bild av perfView-upplösningAttempterade händelser

Händelsenamn Sammanställningsnamn Etapp Resultat
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

Händelserna ovan anger att sammansättningsinläsaren försökte lösa sammansättningen genom att titta i den aktuella belastningskontexten, köra standardlogik för avsökning för hanterade programsammansättningar, anropa hanterare för AssemblyLoadContext.Resolving händelsen och anropa hanterare för AppDomain.AssemblyResolve. För alla dessa steg hittades inte sammansättningen.

Tilläggspunkter

Om du vill se vilka tilläggspunkter som anropades filtrera vyn till AssemblyLoadContextResolvingHandlerInvoked och AppDomainAssemblyResolveHandlerInvoked under Microsoft-Windows-DotNETRuntime/AssemblyLoader genom att använda händelselistan till vänster. Lägg till kolumnerna AssemblyName och HandlerName i vyn. Filtrera efter händelser med aktivitets-ID:t från Start/Stop paret.

Bild av händelsepunkter för PerfView-tillägg

Händelsenamn Sammanställningsnamn HanterarNamn
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAppDomainAssemblyResolve

Händelserna ovan anger att en hanterare med namnet OnAssemblyLoadContextResolving anropades för AssemblyLoadContext.Resolving händelsen och att en hanterare med namnet OnAppDomainAssemblyResolve anropades för AppDomain.AssemblyResolve händelsen.

Samla in en annan spårning

Kör programmet med argument som gör att dess hanterare för AssemblyLoadContext.Resolving händelsen läser in MyLibrary sammansättningen.

AssemblyLoading /d default alc-resolving

Samla in och öppna en annan .nettrace fil med hjälp av stegen ovan.

Filtrera till Start- och Stop-händelserna för MyLibrary igen. Du bör se ett Start/Stop par och ett annat Start/Stop däremellan. Inre laddningsoperationen representerar den laddning som utlöstes av hanteraren för AssemblyLoadContext.Resolving när den anropade AssemblyLoadContext.LoadFromAssemblyPath. Den här gången bör du se Success=True vid Stop-händelsen, vilket anger att belastningen lyckades. Fältet ResultAssemblyPath visar sökvägen till den resulterande sammansättningen.

Bild av lyckade Start- och stopphändelser i PerfView

Händelsenamn Sammanställningsnamn Aktivitets-ID Framgång 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/ Sann C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ Sann C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

Vi kan sedan titta på ResolutionAttempted händelserna med aktivitets-ID:t från den externa laddningen för att fastställa vid vilket steg assemblin framgångsrikt har lösts. Den här gången visar händelserna att AssemblyLoadContextResolvingEvent fasen lyckades. Fältet ResultAssemblyPath visar sökvägen till den resulterande sammansättningen.

Bild av lyckade ResolutionAttempted-händelser i PerfView

Händelsenamn Sammanställningsnamn Etapp Resultat 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

Genom att titta på händelser för AssemblyLoadContextResolvingHandlerInvoked kommer det att visa att hanteraren med namnet OnAssemblyLoadContextResolving anropades. Fältet ResultAssemblyPath visar sökvägen till sammansättningen som returneras av hanteraren.

Bild av händelser på PerfView-tilläggspunkt

Händelsenamn Sammanställningsnamn HanterarNamn ResultAssemblyPath
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

Observera att det inte längre finns någon ResolutionAttempted-händelse kopplad till AppDomainAssemblyResolveEvent-fasen eller några AppDomainAssemblyResolveHandlerInvoked-händelser, eftersom montering slutfördes innan steget i inläsningsalgoritmen som genererar AppDomain.AssemblyResolve-händelsen nåddes.

Se även