Error de bloqueo del cargador


95

Estoy construyendo en C ++ dll, escribiendo código en C #.

Me sale un error diciendo

Se detectó LoaderLock Mensaje: Intentando ejecución administrada dentro del bloqueo de OS Loader. No intente ejecutar código administrado dentro de una función de inicialización de imagen o DllMain ya que hacerlo puede hacer que la aplicación se bloquee.

Intenté buscar qué significa exactamente este error, pero estoy dibujando artículos sin sentido, en su mayoría diciendo que es solo una advertencia, y debería desactivarlo en Visual Studio. Las otras soluciones parecen deberse a ITunes, o este problema se produce al programar con DirectX. Mi problema no está relacionado con ninguno.

¿Alguien puede explicar qué significa esto realmente?


Siento que contigo, tengo el mismo problema, y ​​lo que más me sorprende: mi dll ni siquiera es código administrado, entonces, ¿por qué / cómo se supone que debe usar código administrado en el DllMain (inexistente)?
Sam

Recibí esta advertencia al intentar ver el contenido de un conjunto de datos en modo de depuración. Estoy usando c #, sucedió en un formulario de Windows normal.
Soenhay

Como no puede averiguar la causa (como comentó en la respuesta superior), sospecho que hay una dll que está cargando y que está cometiendo el crimen.
John Thoits

Respuestas:


70

debe ir al menú Depurar -> Excepciones, abrir los Asistentes de depuración administrados, buscar LoaderLock y desmarcar

http://goo.gl/TGAHV


21
sí, esta es la forma de apagar la advertencia; Pero incluso después de 2 años no he descubierto exactamente por qué estaba sucediendo.
Devdatta Tengshe

2
Esto me pasó al abrir un proyecto antiguo en VS 2012
4imble

1
Estoy contigo @Kohan También abrí un proyecto anterior y obtuve el error. He desactivado la excepción, pero me gustaría saber qué se puede hacer para evitarlo.
Pimenta

1
Si ejecuto el proyecto como depuración nativa, con todas las excepciones predeterminadas (restablecer todo), la ventana de depuración muestra <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - Intento de ejecución administrada dentro del bloqueo de OS Loader .... etc -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS luego presenta múltiples puntos de interrupción durante la secuencia CTOR. Desactivar la configuración de LoaderLock no ayuda. Para mí, tuve que marcar la opción superior de MDA (para TODOS los MDA), luego desmarcar la opción de nivel superior (sin MDA), luego construir + ejecutar. Esto no funcionó para mi colega.
GilesDMiddleton

17
Quería compartir una actualización en VS2015, ahora debe ir a Debug->Windows->Exception Settings. El resto es igual conManaged Debugging Assistants \ LoaderLock
jxramos

52

La idea general del bloqueo del cargador: el sistema ejecuta el código en DllMain dentro de un bloqueo (como en el bloqueo de sincronización). Por lo tanto, ejecutar código no trivial dentro de DllMain es "solicitar un interbloqueo", como se describe aquí .

La pregunta es, ¿por qué intenta ejecutar código dentro de DllMain? ¿Es crucial que este código se ejecute dentro del contexto de DllMain o puede generar un nuevo hilo y ejecutar el código en él, y no esperar a que el código termine de ejecutarse dentro de DllMain?

Creo que el problema con el código administrado específicamente, es que ejecutar código administrado podría implicar cargar el CLR y cosas por el estilo y no se sabe qué podría suceder allí que resultaría en un punto muerto ... No prestaría atención al consejo de "deshabilitar esta advertencia "si yo fuera usted, porque la mayoría de las posibilidades es que sus aplicaciones se cuelguen inesperadamente en algunos escenarios.


4
Estoy trabajando en una aplicación Direct3D. Este es un EXE. Sin embargo, sigo viendo este error. ¿Alguna idea de cómo solucionarlo mejor?
Agnel Kurian

18

ACTUALIZACIÓN PARA .NET 4.0 Y MÁS RECIENTES MARCOS

Esta es una vieja pregunta que se hacía en el momento de .Net 2.0, cuando el soporte para DLL de modo mixto tenía serios problemas de inicialización, propensos a bloqueos aleatorios. A partir de .Net 4.0, la inicialización de las DLL de modo mixto ha cambiado. Ahora hay dos etapas separadas de inicialización:

  1. Inicialización nativa, llamada en el punto de entrada de la DLL, que incluye la configuración nativa en tiempo de ejecución de C ++ y la ejecución de su método DllMain.
  2. Inicialización administrada, ejecutada automáticamente por el cargador del sistema.

Dado que el paso 2 se realiza fuera del bloqueo del cargador, no hay puntos muertos. Los detalles se describen en Inicialización de ensamblajes mixtos .

Para asegurarse de que su ensamblado de modo mixto se pueda cargar desde un ejecutable nativo, lo único que necesita verificar es que el método DllMain esté declarado como código nativo. #pragma unmanagedpodría ayudar aquí:

#pragma unmanaged

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

También es importante que cualquier código al que DllMain pueda llamar directa o indirectamente tampoco esté administrado. Tiene sentido limitar el tipo de funcionalidad utilizada por DllMain para que pueda rastrear todo el código accesible desde DllMain y asegurarse de que todo esté compilado #pragma unmanaged.

El compilador ayuda un poco al advertirle a C4747 si detecta que DllMain no está declarado como no administrado:

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

Sin embargo, el compilador no generará ninguna advertencia si DllMain llama indirectamente a alguna otra función administrada, por lo que debe asegurarse de que eso nunca suceda, de lo contrario, su aplicación podría bloquearse aleatoriamente.


6

Presione ctr d + e Luego, gaste el nodo de asistentes de depuración administrados. Luego desmarcó LoaderLock.

Espero que esto te ayudará.


El atajo es alt + d + x
Narayan

3
El acceso directo en realidad depende de la configuración que haya especificado para usar durante la primera ejecución. El diseño de acceso directo de C # es (Ctrl + D, E). (También puede asignar cualquier combinación de teclas a esta función en Opciones-> Entorno-> Teclado.)
Adam LS

5

recuerde amablemente a los usuarios de VS2017 que debe deshabilitar el " asistente de excepción " en lugar del " asistente de excepción " (antes de VS2017) para evitar el error de bloqueo del cargador, cuya ruta de configuración es Debug-> Exception . Simplemente corrí con este problema y perdí 2 horas buscando soluciones ...


No tengo "Excepción" en "Depurar". Tengo la comunidad VS2017 15.8.4
Alex

@Alex, verifique Debug -> Windows -> Configuración de excepción, o presione Ctrl + Alt + E
mistika

4

Recientemente recibí este error al crear una instancia de un objeto COM escrito en código nativo:

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

Esto condujo al error descrito. Se detectó un "LoaderLock": se lanzó una excepción.

Superé este error creando la instancia de objeto en un hilo adicional:

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

myThread.Start();
myThread.Join(); // for synchronization

El error puede ocurrir con objetos remotables (MarshalByRefObject), y esta solución no funciona para ellos.
Matthieu

3

Estoy construyendo una DLL C ++ CLR (MSVS2015) que tiene que hacer llamadas a una DLL no administrada y definir código no administrado. Utilizo #pragma administrado y #pragma no administrado para controlar en qué modo se encuentra para un área determinada del código.

En mi caso, simplemente puse #pragma sin administrar frente a mi DllMain () y esto resolvió el problema. Parecía estar pensando que quería una versión administrada de DllMain ().



2

La ruta de configuración en mi instancia de Visual Studio 2017 es Depurar -> Windows -> Configuración de excepción. La "ventana" de configuración de excepciones apareció en el grupo de pestañas inferior (a diferencia de una ventana separada), me tomó un tiempo darme cuenta. Busque "cargador".

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.