Помощник по отладке управляемого кода loaderLock
Помощник по отладке управляемого кода (MDA) loaderLock выявляет попытки выполнения управляемого кода в потоке, содержащем блокировку загрузчика операционной системы Microsoft Windows. Подобное выполнение кода не разрешено, поскольку может привести к взаимоблокировке и использованию библиотек DLL прежде, чем они будут инициализированы загрузчиком операционной системы.
Признаки
Чаще всего при выполнении кода в блокировке загрузчика операционной системы происходит следующий сбой: потоки взаимоблокируются при попытке вызова других функций Win32, для которых также требуется блокировка загрузчика. Примерами таких функций являются LoadLibrary, GetProcAddress, FreeLibrary и GetModuleHandle. Возможно, данные функции не были вызваны непосредственно приложением; среда выполнения CLR также могла вызвать эти функции в результате вызовов более высокого уровня, например Load или первого вызова метода вызова неуправляемого кода.
Взаимоблокировка также может произойти в том случае, если поток ожидает запуска или завершения работы другого потока. При запуске или завершении работы поток должен получить блокировку загрузчика операционной системы, чтобы доставить события в соответствующие связанные библиотеки DLL.
Кроме этого, в некоторых случаях вызовы библиотек DLL могут произойти до того, как данные библиотеки должным образом будут инициализированы загрузчиком операционной системы. В отличие от сбоев по причине взаимоблокировки, которые можно диагностировать, исследуя стеки всех потоков во взаимоблокировке, диагностировать использование неинициализированных библиотек DLL без данного помощника по отладке управляемого кода очень сложно.
Причина
Смешанные управляемые/неуправляемые сборки C++ для .NET Framework версий 1.0 или 1.1, как правило, пытаются выполнить управляемый код в блокировке загрузчика, если только соответствующие меры не приняты заранее (например, связывание с /NOENTRY). Подробное описание данных проблем см. в статьи "Проблемы при загрузке смешанных библиотек DLL" в библиотеке MSDN.
В смешанных сборках C++ для .NET Framework версии 2.0 такие проблемы менее вероятны, как и в приложениях, использующих неуправляемые библиотеки DLL, не соответствующие правилам операционной системы. Например, если точка входа DllMain неуправляемой библиотеки DLL вызывает метод CoCreateInstance, чтобы получить управляемый объект, предоставленный модели СОМ, результатом является попытка выполнения управляемого кода в блокировке загрузчика. Дополнительные сведения о проблемах блокировки загрузчика в платформе .NET Framework 2.0 и более поздних версий см. в разделе Инициализация смешанных сборок.
Решение
В Visual C++ .NET 2002 и Visual C++ .NET 2003 библиотеки DLL, которые компилируются с параметром /clr, могут случайным образом создать ситуацию взаимоблокировки при загрузке. Подобная ситуация называется проблемой загрузки смешанных библиотек DLL или блокировки загрузчика. В Visual C++ 2005 и более поздних версиях почти все недетерминированные ситуации при загрузке смешанных библиотек DLL исключены. Однако остаются несколько определенных случаев, в которых может произойти блокировка загрузчика. Подробные сведения о причинах остальных проблем блокировки загрузчика и их решениях см. в разделе Инициализация смешанных сборок. Если с помощью данного раздела не удалось решить проблему блокировки загрузчика, следует изучить стек потока, чтобы определить причину возникновения блокировки загрузчика и найти способы ее устранения. Следует изучить трассировку стека для потока, который активировал данный помощник по отладке управляемого кода. Поток пытается выполнить недопустимый вызов управляемого кода, сохраняя при этом блокировку загрузчика операционной системы. Вероятно, в стеке появится точка входа DllMain библиотеки DLL или эквивалентная точка входа. Правила операционной системы, определяющие допустимые действия из такой точки входа, достаточно ограничены. Данные правила исключают любое управляемое выполнение.
Влияние на среду выполнения
Как правило, взаимоблокировке подвержены несколько потоков в процессе. Одним из таких потоков, скорее всего, будет поток, отвечающий за сборку мусора, поэтому взаимоблокировка может оказать значительное влияние на процесс в целом. Более того, это помешает любым дополнительным операциям, для которых требуется блокировка загрузчика операционной системы, например загрузке и выгрузке сборок или библиотек DLL, а также запуску или остановке потоков.
В отдельных случаях также возможно нарушение прав доступа или сходные проблемы в библиотеках DLL, которые вызываются до инициализации.
Output
Помощник по отладке управляемого кода сообщает о попытке недопустимого управляемого выполнения. Следует изучить стек потока, чтобы определить причину и возникновения блокировки загрузчика и способы решения проблемы.
Конфигурация
<mdaConfig>
<assistants>
<loaderLock/>
</assistants>
</mdaConfig>
См. также
Основные понятия
Диагностика ошибок посредством управляемых помощников по отладке