Errore di blocco del caricatore


95

Sto costruendo su C ++ dll, scrivendo codice in C #.

Ottengo un errore, dicendo

LoaderLock è stato rilevato Messaggio: tentativo di esecuzione gestita all'interno del blocco OS Loader. Non tentare di eseguire codice gestito all'interno di una funzione di inizializzazione di DllMain o immagine poiché ciò può causare il blocco dell'applicazione.

Ho provato a ricercare il significato di questo errore, ma sto disegnando articoli inutili, principalmente dicendo che è solo un avvertimento e dovrei disattivarlo in Visual Studio. Le altre soluzioni sembrano essere dovute a iTunes, o questo problema si verifica durante la programmazione con DirectX. Il mio problema non è collegato a nessuno dei due.

Qualcuno può spiegare cosa significa in realtà?


Mi sento con te, ho lo stesso problema e ciò che mi sorprende di più: la mia dll non è nemmeno codice gestito, quindi perché / come dovrebbe usare codice gestito sul (inesistente) DllMain ??
Sam

Ho ricevuto questo avviso durante il tentativo di visualizzare il contenuto di un set di dati in modalità di debug. Sto usando c #, è successo in una normale forma di Windows.
Soenhay

Dato che non riesci a capire la causa (come hai commentato nella risposta in alto), sospetto che ci sia una DLL che stai caricando che sta commettendo il crimine.
John Thoits,

Risposte:


70

devi andare al menu Debug -> Eccezioni, aprire gli assistenti di debug gestiti, trovare LoaderLock e deselezionare

http://goo.gl/TGAHV


21
sì, questo è il modo per disattivare l'avviso; Ma anche dopo 2 anni non ho capito esattamente perché stava accadendo.
Devdatta Tengshe

2
Questo è successo a me aprendo un vecchio progetto in VS 2012
4imble

1
Sono con te @Kohan Ho anche aperto un vecchio progetto e ho ricevuto l'errore. Ho disabilitato l'eccezione ma vorrei capire cosa si può fare per impedirlo.
Pimenta

1
Se eseguo il progetto come debug nativo, con tutte le eccezioni di default (ripristina tutto), la finestra di debug mostra <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - Tentativo di esecuzione gestita all'interno del blocco OS Loader .... ecc -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS presenta quindi più punti di interruzione durante la sequenza CTOR. La disattivazione dell'impostazione LoaderLock non aiuta. Per me, ho dovuto spuntare l'opzione MDA in alto (per TUTTI MDA) quindi deselezionare l'opzione di livello superiore (per nessun MDA), quindi build + run. Questo non ha funzionato per il mio collega.
GilesDMiddleton

17
Volevo condividere un aggiornamento in VS2015, ora devi andare a Debug->Windows->Exception Settings. Il resto è lo stesso conManaged Debugging Assistants \ LoaderLock
jxramos

52

L'idea generale del blocco del caricatore: il sistema esegue il codice in DllMain all'interno di un blocco (come un blocco di sincronizzazione). Pertanto, l'esecuzione di codice non banale all'interno di DllMain "richiede un deadlock", come descritto di seguito .

La domanda è: perché stai cercando di eseguire il codice all'interno di DllMain? È fondamentale che questo codice venga eseguito all'interno del contesto di DllMain o è possibile generare un nuovo thread ed eseguire il codice in esso e non attendere che il codice termini l'esecuzione all'interno di DllMain?

Credo che il problema con il codice gestito in particolare sia che l'esecuzione di codice gestito potrebbe comportare il caricamento di CLR e simili e non si sa cosa potrebbe accadere lì che comporterebbe un deadlock ... Non ascolterei il consiglio di "disabilitare questo avviso "Se fossi in te, è molto probabile che le tue applicazioni si blocchino in modo imprevisto in alcuni scenari.


4
Sto lavorando a un'applicazione Direct3D. Questo è un EXE. Tuttavia, continuo a visualizzare questo errore. Qualche idea su come risolvere al meglio questo problema?
Agnel Kurian

18

AGGIORNAMENTO PER .NET 4.0 E ULTERIORI FRAMEWORK

Questa è una vecchia domanda posta al momento di .Net 2.0, quando il supporto per le DLL in modalità mista presentava seri problemi di inizializzazione, soggetti a deadlock casuali. A partire da .Net 4.0, l'inizializzazione delle DLL in modalità mista è cambiata. Ora ci sono due fasi separate di inizializzazione:

  1. Inizializzazione nativa, chiamata al punto di ingresso della DLL, che include l'installazione runtime C ++ nativa e l'esecuzione del metodo DllMain.
  2. Inizializzazione gestita, eseguita automaticamente dal caricatore di sistema.

Poiché il passaggio n. 2 viene eseguito al di fuori del blocco del caricatore, non sono presenti deadlock. I dettagli sono descritti in Inizializzazione di assembly misti .

Per garantire che l'assembly in modalità mista possa essere caricato da un eseguibile nativo, l'unica cosa che devi controllare è che il metodo DllMain sia dichiarato come codice nativo. #pragma unmanagedpotrebbe aiutare qui:

#pragma unmanaged

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

È inoltre importante che qualsiasi codice che DllMain potrebbe chiamare direttamente o indirettamente non sia gestito. Ha senso limitare il tipo di funzionalità utilizzato da DllMain in modo da tenere traccia di tutto il codice raggiungibile da DllMain e assicurarsi che sia tutto compilato #pragma unmanaged.

Il compilatore aiuta un po 'dandoti un avvertimento C4747 se rileva che DllMain non è dichiarato come non gestito:

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

Tuttavia, il compilatore non genererà alcun avviso se DllMain chiama indirettamente qualche altra funzione gestita, quindi è necessario assicurarsi che non accada, altrimenti l'applicazione potrebbe bloccarsi in modo casuale.


6

Premere ctr d + e quindi Expend Managed Debugging Assistants Node. Quindi deselezionato LoaderLock.

Spero che questo ti possa aiutare.


La scorciatoia è alt + d + x
Narayan

3
Il collegamento in realtà dipende dalla configurazione specificata da utilizzare durante la prima esecuzione. Il layout della scorciatoia C # è (Ctrl + D, E). (Inoltre puoi assegnare qualsiasi combinazione di tasti a questa funzione in Opzioni-> Ambiente-> Tastiera.)
Adam LS

5

ricorda gentilmente a quegli utenti di VS2017 che devi disabilitare " helper eccezione " invece di " assistente eccezioni " (prima di VS2017) per evitare errori di blocco del caricatore, il cui percorso di impostazione è Debug-> Eccezione . Mi sono appena imbattuto in questo problema e ho perso 2 ore alla ricerca di soluzioni ...


Non ho "Eccezione" in "Debug". Ho VS2017 Community 15.8.4
Alex

@Alex, controlla Debug -> Windows -> Impostazioni eccezione o premi Ctrl + Alt + E
mistika

4

Recentemente ho ricevuto questo errore durante la creazione di un'istanza di un oggetto COM scritto in codice nativo:

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

Ciò ha portato all'errore descritto. È stata generata un'eccezione "LoaderLock".

Ho superato questo errore creando l'istanza dell'oggetto in un thread aggiuntivo:

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

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

L'errore può verificarsi con oggetti remotabili (MarshalByRefObject) e questa soluzione non funziona per quelli.
Matthieu

3

Sto creando una DLL CLR C ++ (MSVS2015) che deve effettuare chiamate in una DLL non gestita e definire codice non gestito. Uso #pragma managed e #pragma unmanaged per controllare in quale modalità si trova per una determinata area del codice.

Nel mio caso ho semplicemente messo #pragma unmanaged davanti al mio DllMain () e questo ha risolto il problema. Sembrava pensare che volessi una versione gestita di DllMain ().



2

Il percorso di impostazione nella mia istanza di Visual Studio 2017 è Debug -> Windows -> Impostazioni eccezione. La "finestra" delle impostazioni delle eccezioni è stata visualizzata nel gruppo di schede in basso (al contrario di una finestra separata), mi ci è voluto un po 'per notarla. Cerca "loader".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.