Ошибка блокировки загрузчика

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

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

LoaderLock was detected Message: Attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang.

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

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

Я чувствую, что у меня та же проблема, и что меня больше всего удивляет: моя dll даже не является управляемым кодом, так почему / как предполагается использовать управляемый код в (несуществующей) DllMain ??

Sam 05.03.2010 17:04

Я получил это предупреждение при попытке просмотреть содержимое набора данных в режиме отладки. Я использую C#, это произошло в обычной форме Windows.

Soenhay 19.05.2015 17:55

Поскольку вы не можете выяснить причину (как вы прокомментировали в верхнем ответе), я подозреваю, что вы загружаете DLL, которая совершает преступление.

John Thoits 30.01.2019 03:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
95
3
78 233
9

Ответы 9

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

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

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

Я работаю над приложением Direct3D. Это EXE. Однако я все еще вижу эту ошибку. Есть идеи, как это лучше всего исправить?

Agnel Kurian 16.10.2008 14:36

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

http://goo.gl/TGAHV

да, это способ отключить предупреждение; Но даже через 2 года я так и не понял, почему это происходило.

Devdatta Tengshe 04.11.2010 15:41

Получил такую ​​же проблему. При отладке все нормально, но при установке приложения все равно выдает ошибку ...

David Brunelle 23.06.2012 07:49

Это случилось со мной, когда я открывал старый проект в VS 2012

4imble 07.08.2012 13:59

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

Pimenta 14.02.2013 21:44

Если я запускаю проект как отладку в собственном коде со всеми исключениями по умолчанию (сбросить все), в окне отладки отображается <mda: msg xmlns: mda = "schemas.microsoft.com/CLR/2004/10/mda"> <! - Попытка управляемого выполнения внутри блокировки загрузчика ОС .... etc -> <mda: loaderLockMsg break = "true" /> </ mda: msg> Затем VS представляет несколько точек останова во время последовательности CTOR. Отключение параметра LoaderLock не помогает. Что касается меня, мне пришлось отметить верхнюю опцию MDA (для ВСЕХ MDA), затем снять отметку с опции верхнего уровня (без MDA), затем построить + запустить. У моего коллеги это не сработало.

GilesDMiddleton 15.10.2014 16:29

Хотел поделиться обновлением в VS2015, теперь вам нужно перейти на Debug->Windows->Exception Settings. В остальном то же самое с Managed Debugging Assistants \ LoaderLock

jxramos 03.08.2016 22:10

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

Прочтите внимательно: http://msdn.microsoft.com/en-us/library/aa290048(vs.71).aspx

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

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

Ярлык фактически зависит от конфигурации, которую вы указали для использования при первом запуске. Макет ярлыка C# (Ctrl + D, E). (Также вы можете назначить любую комбинацию клавиш для этой функции в Параметры-> Среда-> Клавиатура.)

Adam L. S. 10.06.2016 10:13

Недавно я получил эту ошибку при создании экземпляра 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

Ошибка может произойти с объектами Remotable (MarshalByRefObject), и это решение для них не работает.

Matthieu 16.10.2019 17:26

ОБНОВЛЕНИЕ ДЛЯ .NET 4.0 И БОЛЕЕ НЕДАВНИХ Фреймворков

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

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

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

Чтобы гарантировать, что ваша сборка в смешанном режиме может быть загружена из собственного исполняемого файла, единственное, что вам нужно проверить, - это то, что метод 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 косвенно вызывает какую-либо другую управляемую функцию, поэтому вам нужно убедиться, что этого никогда не произойдет, иначе ваше приложение может случайным образом заблокироваться.

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

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

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

У меня нет «Исключения» в разделе «Отладка». У меня VS2017 Сообщество 15.8.4

Alex 11.10.2018 17:13

@Alex, проверьте Debug -> Windows -> Exception Settings, или нажмите Ctrl + Alt + E

mistika 22.07.2019 20:15

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

Другие вопросы по теме