.NET 5부터 런타임은 EventPipe
에 대한 자세한 정보를 통해 이벤트를 내보낼 수 있습니다. 이러한 이벤트는Microsoft-Windows-DotNETRuntime
공급자가 AssemblyLoader
키워드(0x4
) 아래에서 내보냅니다.
필수 조건
- .NET 5 SDK 이상 버전
-
dotnet-trace
도구
비고
기능의 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
스위치를 사용하여stdin
및stdout
와 상호 작용합니다. -
Ctrl+C를 통해 도구를 종료하거나
SIGTERM
도구와 자식 프로세스를 모두 안전하게 종료합니다. - 자식 프로세스가 툴보다 먼저 종료되면 툴도 종료되고, 추적을 안전하게 볼 수 있습니다.
추적을 확인하기
수집된 추적 파일은 PerfView의 이벤트 보기를 사용하여 Windows에서 볼 수 있습니다. 모든 어셈블리 로드 이벤트는 Microsoft-Windows-DotNETRuntime/AssemblyLoader
로 시작됩니다.
예제(Windows)
이 예제에서는 어셈블리 로드 확장 지점 샘플을 사용합니다. 애플리케이션은 어셈블리를 로드하려고 시도합니다. 어셈블리 MyLibrary
는 애플리케이션에서 참조하지 않으므로 어셈블리 로드 확장 지점에서 처리가 성공적으로 로드되어야 합니다.
추적 데이터 수집
다운로드한 샘플을 사용하여 디렉터리로 이동합니다. 다음을 사용하여 애플리케이션을 빌드합니다.
dotnet build
키 누름을 기다리며 일시 중지해야 함을 나타내는 인수를 사용하여 애플리케이션을 시작합니다. 다시 열 때 성공적으로 로드하는 데 필요한 처리 없이 기본값
AssemblyLoadContext
으로 어셈블리를 로드하려고 시도합니다. 출력 디렉터리로 이동하여 다음을 실행합니다.AssemblyLoading.exe /d default
애플리케이션의 프로세스 ID를 찾습니다.
dotnet-trace ps
출력에는 사용 가능한 프로세스가 나열됩니다. 다음은 그 예입니다.
35832 AssemblyLoading C:\src\AssemblyLoading\bin\Debug\net5.0\AssemblyLoading.exe
실행 중인 애플리케이션
dotnet-trace
에 붙입니다.dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:4 --process-id 35832
애플리케이션을 실행하는 창에서 아무 키나 눌러 프로그램을 계속할 수 있도록 합니다. 애플리케이션이 종료되면 추적이 자동으로 중지됩니다.
추적 보기
PerfView에서 수집된 추적을 열고 이벤트 보기를 엽니다.
Microsoft-Windows-DotNETRuntime/AssemblyLoader
이벤트로 목록을 필터링합니다.
추적이 시작된 후 애플리케이션에서 발생한 모든 어셈블리 로드가 표시됩니다. 이 예제 MyLibrary
에 대해 관심 있는 어셈블리에 대한 부하 작업을 검사하려면 좀 더 필터링을 수행할 수 있습니다.
어셈블리 부하
왼쪽의 이벤트 목록을 사용하여 Start
에 포함된 Stop
및 Microsoft-Windows-DotNETRuntime/AssemblyLoader
이벤트로 뷰를 필터링하세요. 열 AssemblyName
, ActivityID
, 및 Success
를 뷰에 추가합니다.
MyLibrary
을 포함하는 이벤트로 필터링합니다.
이벤트 이름 | 어셈블리 이름 | ActivityID | 성공 |
---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | 거짓 |
로드 작업이 실패했음을 나타내는 Start
와 함께하는 한 쌍의 /Stop
Success=False
이 Stop
이벤트에 표시됩니다. 두 이벤트는 동일한 활동 ID를 갖습니다. 활동 ID를 사용하여 다른 모든 어셈블리 로더 이벤트를 이 로드 작업에 해당하는 이벤트로 필터링할 수 있습니다.
로드 시도 상세 분석
부하 작업을 더 자세히 분석하려면 왼쪽에 있는 이벤트 목록을 사용하여 ResolutionAttempted
아래의 로 보기를 필터링하세요. 열 AssemblyName
, Stage
, 및 Result
를 뷰에 추가합니다.
Start
/
Stop
쌍에서 활동 ID로 필터링된 이벤트를 표시합니다.
이벤트 이름 | 어셈블리 이름 | 단계 | 결과 |
---|---|---|---|
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
아래에서 AppDomainAssemblyResolveHandlerInvoked
및 Microsoft-Windows-DotNETRuntime/AssemblyLoader
로 뷰를 필터링합니다. 뷰에 AssemblyName
열과 HandlerName
열을 추가하세요.
Start
/
Stop
쌍에서 활동 ID로 필터링된 이벤트를 표시합니다.
이벤트 이름 | 어셈블리 이름 | 핸들러 이름 |
---|---|---|
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
사용하여 다른 파일을 수집하고 엽니다.
Start
및 Stop
이벤트를 MyLibrary
에 대해 다시 필터링합니다. 둘 사이에 다른 Start
/Stop
쌍이 Start
/Stop
표시됩니다. 내부 로드 작업은 호출AssemblyLoadContext.Resolving할 때 처리기에 의해 트리거되는 부하를 AssemblyLoadContext.LoadFromAssemblyPath 나타냅니다. 이번에는 Success=True
가 Stop
이벤트에 표시되어 로드 작업이 성공했음을 나타냅니다. 필드에 결과 ResultAssemblyPath
어셈블리의 경로가 표시됩니다.
이벤트 이름 | 어셈블리 이름 | 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
어셈블리의 경로가 표시됩니다.
이벤트 이름 | 어셈블리 이름 | 단계 | 결과 | 결과어셈블리경로 (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
처리기에서 반환된 어셈블리의 경로가 표시됩니다.
이벤트 이름 | 어셈블리 이름 | 핸들러 이름 | 결과어셈블리경로 (ResultAssemblyPath) |
---|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
ResolutionAttempted
이벤트를 발생시키는 로드 알고리즘 단계에 도달하기 전에 어셈블리가 성공적으로 로드되었기 때문에 더 이상 AppDomainAssemblyResolveEvent
이벤트가 AppDomainAssemblyResolveHandlerInvoked
단계에서 발생하지 않으며 AppDomain.AssemblyResolve 이벤트도 발생하지 않습니다.
참고하십시오
.NET