Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Начиная с .NET 5, среда выполнения может выдавать события через EventPipe с подробными сведениями о загрузке управляемых сборок, что помогает в диагностике проблем с их загрузкой. Эти события испускаются поставщиком Microsoft-Windows-DotNETRuntime с помощью ключевого слова AssemblyLoader (0x4).
Предпосылки
- Пакет SDK для .NET 5 или более поздние версии
- Средство
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, чтобы сделать это.
Следующая команда запускает hello.exe с аргументами командной строки 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безопасно завершает как программу, так и дочерний процесс. - Если дочерний процесс завершает работу до утилиты, утилита также завершает работу, и трассировку можно безопасно просмотреть.
Просмотр трассировки
Собранный файл трассировки можно просмотреть в Windows с помощью представления событий в PerfView. Все события загрузки сборки будут префиксированы Microsoft-Windows-DotNETRuntime/AssemblyLoader.
Пример (в Windows)
В этом примере используется пример точек расширения загрузки сборки. Приложение пытается загрузить сборку MyLibrary — сборку, на которую не ссылается приложение, и поэтому требуется обработка в точке расширения загрузки сборки для успешной загрузки.
Соберите трассировку
Перейдите к каталогу с скачанным примером. Создайте приложение с помощью следующих приложений:
dotnet buildЗапустите приложение с аргументами, указывающими, что она должна приостановиться, ожидая нажатия клавиши. При возобновлении она попытается загрузить сборку по умолчанию
AssemblyLoadContextбез обработки, необходимой для успешной загрузки. Перейдите в выходной каталог и выполните следующую команду:AssemblyLoading.exe /d defaultНайдите идентификатор процесса приложения.
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и ActivityIDSuccess в представление. Фильтровать события, содержащие MyLibrary.
| Имя события | Имя сборки | Идентификатор Активности | Успех |
|---|---|---|---|
AssemblyLoader/Start |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | |
AssemblyLoader/Stop |
MyLibrary, Culture=neutral, PublicKeyToken=null |
//1/2/ | Неправда |
Вы увидите одну Start/Stop пару с Success=False событием, указывающую на сбой Stop операции загрузки. Обратите внимание, что два события имеют одинаковый идентификатор действия. Идентификатор действия можно использовать для фильтрации всех других событий загрузчика сборок только тем, которые соответствуют этой операции загрузки.
Разбивка попытки загрузки
Для более подробной детализации операции загрузки фильтруйте представление по ResolutionAttempted событиям под Microsoft-Windows-DotNETRuntime/AssemblyLoader используя список событий слева. Добавьте столбцы AssemblyNameи StageResult в представление. Фильтруйте события с идентификатором действия из пары Start/Stop.
| Имя события | Имя сборки | Этап | Результат |
|---|---|---|---|
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.
| Имя события | Имя сборки | ИмяОбработчика |
|---|---|---|
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 поле показан путь к результирующей сборке.
| Имя события | Имя сборки | Идентификатор Активности | Успех | 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 |
Затем можно просмотреть ResolutionAttempted события с ID активности из внешней загрузки, чтобы определить шаг, на котором сборка была успешно выполнена. На этот раз события покажут, что 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 поле показан путь к сборке, возвращаемой обработчиком.
Изображение успешных событий точки расширения в PerfView
| Имя события | Имя сборки | ИмяОбработчика | ResultAssemblyPath |
|---|---|---|---|
AssemblyLoader/AssemblyLoadContextResolvingHandlerInvoked |
MyLibrary, Culture=neutral, PublicKeyToken=null |
OnAssemblyLoadContextResolving |
C:\src\AssemblyLoading\bin\Debug\net5.0\MyLibrary.dll |
Обратите внимание, что больше не происходит событие ResolutionAttempted с этапом AppDomainAssemblyResolveEvent, а также любые события AppDomainAssemblyResolveHandlerInvoked, поскольку сборка была успешно загружена до того, как алгоритм загрузки достиг шага, вызывающего событие AppDomain.AssemblyResolve.