Помилка блокування навантажувача


95

Я будую на dll C ++, написавши код на C #.

Я отримую повідомлення про помилку

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

Я спробував шукати, що саме означає ця помилка, але я малюю безглузді статті, в основному кажучи, що це лише попередження, і мені слід вимкнути це у Visual Studio. Інші рішення, здається, пов'язані з ITunes, або ця проблема виникає при програмуванні з DirectX. Моя проблема не пов’язана ні з одним, ні з іншим.

Хтось може пояснити, що це насправді означає?


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

Я отримав це попередження під час спроби переглянути вміст набору даних у режимі налагодження. Я використовую c #, це сталося у звичайній формі Windows.
Soenhay

Оскільки ви не можете з'ясувати причину (як ви прокоментували у верхній відповіді), я підозрюю, що ви завантажуєте DLL, який здійснює злочин.
Джон Тойтс,

Відповіді:


70

потрібно зайти в меню Налагодження -> Винятки, відкрити Керовані помічники налагодження, знайти LoaderLock і зняти прапорець

http://goo.gl/TGAHV


21
так, це спосіб вимкнути попередження; Але навіть через 2 роки я не з'ясував, чому саме це відбувалося.
Девдатта Тенгше

2
Це трапилося зі мною, відкриваючи старий проект у VS 2012
4imble

1
Я з вами @Kohan. Я також відкрив старий проект і отримав помилку. Я вимкнув виняток, але хотів би зрозуміти, що можна зробити для запобігання цьому.
Pimenta

1
Якщо я запускаю проект як власну налагодження, за винятком за замовчуванням (скинути всі), у вікні налагодження відображається <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - Спроба керованого виконання всередині блокування завантажувача ОС .... тощо -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS потім представляє кілька точок зупинки під час послідовності CTOR. Вимкнення параметра LoaderLock не допомагає. Для мене мені довелося позначити верхній варіант MDA (для ALL MDA), потім зняти прапорець верхнього рівня (без MDA), а потім побудувати + запустити. У мого колеги це не спрацювало.
GilesDMiddleton

17
Хотіли поділитися оновленням у VS2015, тепер потрібно перейти до Debug->Windows->Exception Settings. Решта те саме зManaged Debugging Assistants \ LoaderLock
jxramos

52

Загальна ідея блокування завантажувача: система запускає код у DllMain всередині блокування (як у - блокування синхронізації). Отже, запуск нетривіального коду всередині DllMain "вимагає глухого кута", як описано тут .

Питання в тому, чому ви намагаєтеся запустити код всередині DllMain? Чи важливо, щоб цей код працював всередині контексту DllMain, або ви можете породити новий потік і запустити в ньому код, а не чекати, поки код завершить виконання всередині DllMain?

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


4
Я працюю над додатком Direct3D. Це EXE. Однак я все ще бачу цю помилку. Будь-які ідеї, як найкраще це виправити?
Аньель Кур'ян,

18

ОНОВЛЕННЯ ДЛЯ .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

Натисніть ctr d + e Потім Витратьте Вузол керованих налагоджувальників. Потім зніміть прапорець LoaderLock.

Сподіваюся, що це вам допоможе.


Комбінація клавіш alt + d + x
Narayan

3
Ярлик фактично залежить від конфігурації, яку ви вказали для використання під час першого запуску. Розкладка ярлика C # (Ctrl + D, E). (Також для цієї функції ви можете призначити будь-яку комбінацію клавіш у меню Параметри-> Навколишнє середовище-> Клавіатура.)
Адам ЛС

5

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


У мене немає "Винятку" в розділі "Налагодження". У мене є VS2017 Community 15.8.4
Alex,

@Alex, перевірте налагодження -> Windows -> Налаштування винятків, або натисніть Ctrl + Alt + E
mistika

4

Нещодавно я отримав цю помилку під час створення екземпляра 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

Помилка може статися з віддаленими об'єктами (MarshalByRefObject), і це рішення для них не працює.
Matthieu

3

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

У моєму випадку я просто поставив #pragma некерованим перед моїм DllMain (), і це вирішило проблему. Здавалося, я думав, що хочу керовану версію DllMain ().



2

Шлях налаштування в моєму екземплярі Visual Studio 2017 - це Налагодження -> Windows -> Налаштування винятків. Налаштування винятків "вікно" з'явилося в нижній групі вкладок (на відміну від окремого вікна), і це зайняло деякий час, щоб помітити це. Шукати "навантажувач".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.