다음을 통해 공유


자세한 어셈블리 로딩 정보 수집

.NET 5부터 런타임은 EventPipe에 대한 자세한 정보를 통해 이벤트를 내보낼 수 있습니다. 이러한 이벤트는Microsoft-Windows-DotNETRuntime 공급자가 AssemblyLoader 키워드(0x4) 아래에서 내보냅니다.

필수 조건

비고

기능의 dotnet-trace 범위는 자세한 어셈블리 로드 정보를 수집하는 것보다 큽합니다. 사용 현황 dotnet-trace에 대한 자세한 내용은 다음을 참조하세요 dotnet-trace.

어셈블리 로드 이벤트를 사용하여 추적 수집

기존 프로세스를 추적하거나 자식 프로세스를 시작하고 시작부터 추적하는 데 사용할 dotnet-trace 수 있습니다.

기존 프로세스 추적

런타임에서 어셈블리 로드 이벤트를 사용하도록 설정하고 추적을 수집하려면 다음 명령을 사용합니다 dotnet-trace .

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

이 명령은 지정한 <pid>의 추적을 수집하여 AssemblyLoader 공급자에서 Microsoft-Windows-DotNETRuntime 이벤트를 활성화합니다. 결과는 .nettrace 파일입니다.

dotnet-trace를 사용하여 자식 프로세스를 시작하고 프로세스 시작부터 추적합니다.

경우에 따라 시작에서 프로세스의 추적을 수집하는 것이 유용할 수 있습니다. .NET 5 이상을 실행하는 앱의 경우 이 작업을 수행하는 데 사용할 dotnet-trace 수 있습니다.

다음 명령은 arg1를 명령줄 인수로 사용하여 arg2를 실행하고 런타임 시작 시점에서 추적을 수집합니다.

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

Enter 키 또는 Ctrl + C를 눌러 추적 수집을 중지할 수 있습니다. 또한 hello.exe닫힙니다.

비고

  • hello.exe를 시작하면 dotnet-trace 입력과 출력이 리디렉션되어 디폴트로 콘솔에서 이 프로그램과 상호 작용할 수 없습니다. --show-child-io 스위치를 사용하여 stdinstdout와 상호 작용합니다.
  • Ctrl+C를 통해 도구를 종료하거나 SIGTERM 도구와 자식 프로세스를 모두 안전하게 종료합니다.
  • 자식 프로세스가 툴보다 먼저 종료되면 툴도 종료되고, 추적을 안전하게 볼 수 있습니다.

추적을 확인하기

수집된 추적 파일은 PerfView의 이벤트 보기를 사용하여 Windows에서 볼 수 있습니다. 모든 어셈블리 로드 이벤트는 Microsoft-Windows-DotNETRuntime/AssemblyLoader로 시작됩니다.

예제(Windows)

이 예제에서는 어셈블리 로드 확장 지점 샘플을 사용합니다. 애플리케이션은 어셈블리를 로드하려고 시도합니다. 어셈블리 MyLibrary 는 애플리케이션에서 참조하지 않으므로 어셈블리 로드 확장 지점에서 처리가 성공적으로 로드되어야 합니다.

추적 데이터 수집

  1. 다운로드한 샘플을 사용하여 디렉터리로 이동합니다. 다음을 사용하여 애플리케이션을 빌드합니다.

    dotnet build
    
  2. 키 누름을 기다리며 일시 중지해야 함을 나타내는 인수를 사용하여 애플리케이션을 시작합니다. 다시 열 때 성공적으로 로드하는 데 필요한 처리 없이 기본값 AssemblyLoadContext 으로 어셈블리를 로드하려고 시도합니다. 출력 디렉터리로 이동하여 다음을 실행합니다.

    AssemblyLoading.exe /d default
    
  3. 애플리케이션의 프로세스 ID를 찾습니다.

    dotnet-trace ps
    

    출력에는 사용 가능한 프로세스가 나열됩니다. 다음은 그 예입니다.

    35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
    
  4. 실행 중인 애플리케이션dotnet-trace에 붙입니다.

    dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
    
  5. 애플리케이션을 실행하는 창에서 아무 키나 눌러 프로그램을 계속할 수 있도록 합니다. 애플리케이션이 종료되면 추적이 자동으로 중지됩니다.

추적 보기

PerfView에서 수집된 추적을 열고 이벤트 보기를 엽니다. Microsoft-Windows-DotNETRuntime/AssemblyLoader 이벤트로 목록을 필터링합니다.

PerfView 어셈블리 로더 필터 이미지

추적이 시작된 후 애플리케이션에서 발생한 모든 어셈블리 로드가 표시됩니다. 이 예제 MyLibrary에 대해 관심 있는 어셈블리에 대한 부하 작업을 검사하려면 좀 더 필터링을 수행할 수 있습니다.

어셈블리 부하

왼쪽의 이벤트 목록을 사용하여 Start에 포함된 StopMicrosoft-Windows-DotNETRuntime/AssemblyLoader 이벤트로 뷰를 필터링하세요. 열 AssemblyName, ActivityID, 및 Success를 뷰에 추가합니다. MyLibrary을 포함하는 이벤트로 필터링합니다.

PerfView 시작 및 중지 이벤트 이미지

이벤트 이름 어셈블리 이름 ActivityID 성공
AssemblyLoader/Start MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ 거짓

로드 작업이 실패했음을 나타내는 Start와 함께하는 한 쌍의 /StopSuccess=FalseStop 이벤트에 표시됩니다. 두 이벤트는 동일한 활동 ID를 갖습니다. 활동 ID를 사용하여 다른 모든 어셈블리 로더 이벤트를 이 로드 작업에 해당하는 이벤트로 필터링할 수 있습니다.

로드 시도 상세 분석

부하 작업을 더 자세히 분석하려면 왼쪽에 있는 이벤트 목록을 사용하여 ResolutionAttempted 아래의 로 보기를 필터링하세요. 열 AssemblyName, Stage, 및 Result를 뷰에 추가합니다. Start / Stop 쌍에서 활동 ID로 필터링된 이벤트를 표시합니다.

PerfView 해상도 시도 이벤트 이미지

이벤트 이름 어셈블리 이름 단계 결과
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

위의 이벤트는 어셈블리 로더가 현재 부하 컨텍스트를 살펴보고, 관리되는 애플리케이션 어셈블리에 대한 기본 검색 논리를 실행하고, 이벤트에 대한 AssemblyLoadContext.Resolving 처리기를 호출하고, 처리기를 AppDomain.AssemblyResolve호출하여 어셈블리를 확인하려고 했음을 나타냅니다. 이러한 모든 단계에서 어셈블리를 찾을 수 없습니다.

확장 포인트

호출된 확장 지점을 확인하려면 왼쪽의 이벤트 목록을 사용하여, AssemblyLoadContextResolvingHandlerInvoked 아래에서 AppDomainAssemblyResolveHandlerInvokedMicrosoft-Windows-DotNETRuntime/AssemblyLoader로 뷰를 필터링합니다. 뷰에 AssemblyName 열과 HandlerName 열을 추가하세요. Start / Stop 쌍에서 활동 ID로 필터링된 이벤트를 표시합니다.

PerfView 확장 지점 이벤트 이미지

이벤트 이름 어셈블리 이름 핸들러 이름
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving
AssemblyLoader/AppDomainAssemblyResolveHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAppDomainAssemblyResolve

위의 이벤트는 이벤트에 대해 OnAssemblyLoadContextResolving 명명 AssemblyLoadContext.Resolving 된 처리기가 호출되었고 해당 이벤트에 대해 OnAppDomainAssemblyResolve 명명 AppDomain.AssemblyResolve 된 처리기가 호출되었음을 나타냅니다.

또 다른 흔적을 수집하세요.

애플리케이션을 AssemblyLoadContext.Resolving 인수를 사용해 실행하여, MyLibrary 어셈블리를 로드할 수 있는 방식으로 이벤트의 처리기를 작동시킵니다.

AssemblyLoading /d default alc-resolving

.nettrace 사용하여 다른 파일을 수집하고 엽니다.

StartStop 이벤트를 MyLibrary에 대해 다시 필터링합니다. 둘 사이에 다른 Start/Stop 쌍이 Start/Stop 표시됩니다. 내부 로드 작업은 호출AssemblyLoadContext.Resolving할 때 처리기에 의해 트리거되는 부하를 AssemblyLoadContext.LoadFromAssemblyPath 나타냅니다. 이번에는 Success=TrueStop 이벤트에 표시되어 로드 작업이 성공했음을 나타냅니다. 필드에 결과 ResultAssemblyPath 어셈블리의 경로가 표시됩니다.

PerfView 성공적인 시작 및 중지 이벤트 이미지

이벤트 이름 어셈블리 이름 ActivityID 성공 결과어셈블리경로 (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/ 진실 C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll
AssemblyLoader/Stop MyLibrary, Culture=neutral, PublicKeyToken=null //1/2/ 진실 C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

그런 다음, 외부 로드의 활동 ID가 있는 이벤트를 확인 ResolutionAttempted 하여 어셈블리가 성공적으로 해결된 단계를 확인할 수 있습니다. 이번에는, 이 이벤트들이 AssemblyLoadContextResolvingEvent 스테이지가 성공적이었다는 것을 보여줍니다. 필드에 결과 ResultAssemblyPath 어셈블리의 경로가 표시됩니다.

PerfView 성공적인 해결 시도 이벤트 이미지

이벤트 이름 어셈블리 이름 단계 결과 결과어셈블리경로 (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

이벤트를 살펴보면 AssemblyLoadContextResolvingHandlerInvoked 명명 OnAssemblyLoadContextResolving 된 처리기가 호출되었음을 보여 줍니다. 필드에는 ResultAssemblyPath 처리기에서 반환된 어셈블리의 경로가 표시됩니다.

PerfView 성공적인 확장 지점 이벤트 이미지

이벤트 이름 어셈블리 이름 핸들러 이름 결과어셈블리경로 (ResultAssemblyPath)
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked MyLibrary, Culture=neutral, PublicKeyToken=null OnAssemblyLoadContextResolving C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll

ResolutionAttempted 이벤트를 발생시키는 로드 알고리즘 단계에 도달하기 전에 어셈블리가 성공적으로 로드되었기 때문에 더 이상 AppDomainAssemblyResolveEvent 이벤트가 AppDomainAssemblyResolveHandlerInvoked 단계에서 발생하지 않으며 AppDomain.AssemblyResolve 이벤트도 발생하지 않습니다.

참고하십시오