Ошибка блокировки загрузчика - PullRequest
85 голосов
/ 11 сентября 2008

Я строю на C ++ DLL, написав код на C #.

Я получаю сообщение об ошибке

LoaderLock был обнаружен Сообщение: Попытка управляемого исполнения внутри ОС Блокировка погрузчика. Не пытайтесь бежать управляемый код внутри DllMain или изображения функция инициализации, так как это делает может привести к зависанию приложения.

Я попытался выяснить, что именно означает эта ошибка, но я рисую бессмысленные статьи, в основном говоря, что это всего лишь предупреждение, и я должен отключить это в Visual Studio. Похоже, что другие решения связаны с ITunes, или эта проблема возникает при программировании с DirectX Моя проблема не связана ни с одним из них.

Кто-нибудь может объяснить, что это на самом деле означает?

Ответы [ 9 ]

63 голосов
/ 04 ноября 2010

вам нужно перейти в меню «Отладка» -> «Исключения», открыть помощников по управляемой отладке, найти LoaderLock и снять флажок

http://goo.gl/TGAHV

49 голосов
/ 11 сентября 2008

Общая идея блокировки загрузчика: Система запускает код в DllMain внутри блокировки (как при синхронизации синхронизации). Следовательно, выполнение нетривиального кода внутри DllMain - это «запрос тупика», как описано здесь .

Вопрос в том, почему вы пытаетесь запустить код внутри DllMain? Крайне важно, чтобы этот код выполнялся в контексте DllMain, или вы можете создать новый поток и запустить код в нем, а не ждать, пока код завершит выполнение внутри DllMain?

Я полагаю, что проблема, в частности, с управляемым кодом, заключается в том, что запуск управляемого кода может включать в себя загрузку CLR и тому подобное, и никто не знает, что может произойти, что приведет к тупику ... Я бы не послушал совета отключите это предупреждение ", если бы я был вами, потому что, скорее всего, вы обнаружите, что ваши приложения неожиданно зависают при некоторых сценариях.

14 голосов
/ 21 марта 2016

ОБНОВЛЕНИЕ ДЛЯ .NET 4.0 И БОЛЕЕ ПОСЛЕДНИЕ РАМКИ

Это старый вопрос, который задавался во времена .Net 2.0, когда поддержка DLL-библиотек смешанного режима имела серьезные проблемы с инициализацией, склонные к случайным тупикам. Начиная с .Net 4.0, инициализация DLL смешанного режима изменилась. Теперь есть две отдельные стадии инициализации:

  1. Собственная инициализация, вызываемая в точке входа DLL, которая включает в себя собственную настройку C ++ во время выполнения и выполнение вашего метода DllMain.
  2. Управляемая инициализация, автоматически выполняемая системным загрузчиком.

Поскольку шаг № 2 выполняется вне блокировки загрузчика, взаимоблокировки отсутствуют. Подробности описаны в Инициализация смешанных сборок .

Чтобы гарантировать, что ваша сборка смешанного режима может быть загружена из собственного исполняемого файла, единственное, что вам нужно проверить, - это то, что метод DllMain объявлен как собственный код. #pragma unmanaged может помочь здесь:

#pragma unmanaged

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
{
    ... // your implementation here
}

Также важно, чтобы любой код, который DllMain мог вызывать прямо или косвенно, также был неуправляемым. Имеет смысл ограничить тип функциональности, используемой DllMain, чтобы вы могли отслеживать весь код, доступный из DllMain, и убедиться, что он весь скомпилирован с #pragma unmanaged.

Компилятор немного помогает, давая вам предупреждение C4747, если он обнаруживает, что DllMain не объявлен как неуправляемый:

1>  Generating Code...
1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint

Однако компилятор не будет генерировать никаких предупреждений, если DllMain косвенно вызовет какую-то другую управляемую функцию, поэтому вы должны убедиться, что этого никогда не произойдет, иначе ваше приложение может случайно заблокироваться.

6 голосов
/ 18 июля 2012

Нажмите ctr d + e, затем закройте узел Помощники управляемых отладчиков. Затем снимите флажок LoaderLock.

Надеюсь, это поможет вам.

4 голосов
/ 19 мая 2018

Напоминаем пользователям VS2017 , что вам нужно отключить " помощник по исключениям " вместо " помощник по исключениям " (до VS2017), чтобы предотвратить блокировку загрузчика ошибка, путь установки которой Debug-> Exception . Просто побежал к этой проблеме и потратил 2 часа на поиски решений ...

3 голосов
/ 15 июля 2016

Я создаю C ++ CLR DLL (MSVS2015), которая должна выполнять вызовы в неуправляемую DLL и определять неуправляемый код. Я использую управляемый #pragma и неуправляемый #pragma, чтобы контролировать, в каком режиме он находится для данной области кода.

В моем случае я просто поставил #pragma неуправляемым перед моим DllMain (), и это решило проблему. Кажется, я думал, что мне нужна управляемая версия DllMain ().

3 голосов
/ 09 июля 2015

Недавно я получил эту ошибку при создании экземпляра COM-объекта, написанного на собственном коде:

m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy"));

Это привело к описанной ошибке. «LoaderLock был обнаружен» - исключение.

Я преодолел эту ошибку, создав экземпляр объекта в дополнительном потоке:

ThreadStart threadRef = new ThreadStart(delegate { m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy")); });
Thread myThread = new Thread(threadRef);

myThread.Start();
myThread.Join(); // for synchronization
2 голосов
/ 13 июля 2012

Эта проблема возникает из-за того, как отладчик в Visual Studio запускает управляемые приложения, использующие классы Microsoft Foundation версии 8.0, в одном или нескольких файлах DLL.

Внимательно прочитайте по адресу: http://msdn.microsoft.com/en-us/library/aa290048(vs.71).aspx

0 голосов
/ 22 октября 2018

Путь к настройке в моем экземпляре Visual Studio 2017: Отладка -> Windows -> Настройки исключений. «Окно» настроек исключений, показанное в нижней вкладке группы (в отличие от отдельного окна), заняло у меня некоторое время, чтобы заметить это. Поиск "погрузчик".

...