Erreur de verrouillage du chargeur


95

Je construis sur dll C ++, en écrivant du code en C #.

Je reçois une erreur en disant

LoaderLock a été détecté Message: Tentative d'exécution gérée dans le verrou du chargeur du système d'exploitation. N'essayez pas d'exécuter du code managé dans une fonction d'initialisation DllMain ou d'image, car cela pourrait entraîner le blocage de l'application.

J'ai essayé de rechercher ce que signifie exactement cette erreur, mais je dessine des articles inutiles, en disant principalement que ce n'est qu'un avertissement, et je devrais désactiver cela dans Visual Studio. Les autres solutions semblent être dues à ITunes, ou à ce problème survenant lors de la programmation avec DirectX. Mon problème n'est lié à aucun des deux.

Quelqu'un peut-il expliquer ce que cela signifie réellement?


Je pense qu'avec vous, j'ai le même problème, et ce qui me surprend le plus: ma dll n'est même pas du code géré, alors pourquoi / comment est-il censé utiliser du code managé sur le (inexistant) DllMain ??
Sam

J'ai reçu cet avertissement en essayant d'afficher le contenu d'un ensemble de données en mode débogage. J'utilise c #, c'est arrivé sous une forme Windows régulière.
Soenhay

Puisque vous ne pouvez pas comprendre la cause (comme vous l'avez commenté dans la réponse du haut), je soupçonne qu'il y a une dll que vous chargez qui commet le crime.
John Thoits

Réponses:


70

vous devez aller dans le menu Déboguer -> Exceptions, ouvrir les assistants de débogage gérés, trouver LoaderLock et décocher

http://goo.gl/TGAHV


21
oui, c'est la manière de désactiver l'avertissement; Mais même après 2 ans, je n'ai pas compris exactement pourquoi cela se passait.
Devdatta Tengshe

2
Cela m'est arrivé lors de l'ouverture d'un ancien projet dans VS 2012
4imble

1
Je suis avec toi @Kohan J'ai également ouvert un ancien projet et j'ai eu l'erreur. J'ai désactivé l'exception mais j'aimerais comprendre ce qui peut être fait pour éviter cela.
Pimenta

1
Si j'exécute le projet en tant que débogage natif, avec toutes les exceptions par défaut (réinitialiser tout), la fenêtre de débogage affiche <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - Tentative d'exécution gérée à l'intérieur du verrou du chargeur du système d'exploitation .... etc -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS présente alors plusieurs points d'arrêt pendant la séquence CTOR. La désactivation du paramètre LoaderLock n'aide pas. Pour moi, je devais cocher l'option MDA supérieure (pour TOUS MDA), puis décocher l'option de niveau supérieur (pour aucun MDA), puis construire + exécuter. Cela n'a pas fonctionné pour mon collègue.
GilesDMiddleton

17
Vous voulez partager une mise à jour dans VS2015, vous devez maintenant aller à Debug->Windows->Exception Settings. Le reste est pareil avecManaged Debugging Assistants \ LoaderLock
jxramos

52

L'idée générale du verrou du chargeur: Le système exécute le code dans DllMain à l'intérieur d'un verrou (comme verrou de synchronisation). Par conséquent, exécuter du code non trivial dans DllMain "demande un blocage", comme décrit ici .

La question est, pourquoi essayez-vous d'exécuter du code dans DllMain? Est-il crucial que ce code s'exécute dans le contexte de DllMain ou pouvez-vous générer un nouveau thread et exécuter le code qu'il contient, et ne pas attendre que le code se termine l'exécution dans DllMain?

Je crois que le problème avec le code géré en particulier, est que l'exécution de code géré peut impliquer le chargement du CLR et autres et on ne sait pas ce qui pourrait s'y passer qui entraînerait un blocage ... Je ne tiendrais pas compte du conseil de "désactiver cet avertissement "si j'étais vous, car il y a de fortes chances que vous constatiez que vos applications se bloquent de manière inattendue dans certains scénarios.


4
Je travaille sur une application Direct3D. Ceci est un EXE. Cependant, je vois toujours cette erreur. Des idées sur la meilleure façon de résoudre ce problème?
Agnel Kurian

18

MISE À JOUR POUR .NET 4.0 ET PLUS DE CADRES RÉCENTS

C'est une vieille question posée à l'époque de .Net 2.0, lorsque la prise en charge des DLL en mode mixte présentait de graves problèmes d'initialisation, sujets à des blocages aléatoires. Depuis .Net 4.0, l'initialisation des DLL en mode mixte a changé. Maintenant, il y a deux étapes distinctes d'initialisation:

  1. Initialisation native, appelée au point d'entrée de la DLL, qui inclut la configuration d'exécution native C ++ et l'exécution de votre méthode DllMain.
  2. Initialisation gérée, exécutée automatiquement par le chargeur système.

Puisque l'étape n ° 2 est effectuée en dehors du verrou du chargeur, il n'y a pas de blocage. Les détails sont décrits dans Initialisation des assemblys mixtes .

Pour vous assurer que votre assembly en mode mixte peut être chargé à partir d'un exécutable natif, la seule chose que vous devez vérifier est que la méthode DllMain est déclarée en tant que code natif. #pragma unmanagedpourrait aider ici:

#pragma unmanaged

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

Il est également important que tout code que DllMain pourrait appeler directement ou indirectement soit également non géré. Il est logique de limiter le type de fonctionnalité utilisée par DllMain afin de suivre tout le code accessible à partir de DllMain et de vous assurer qu'il est entièrement compilé avec #pragma unmanaged.

Le compilateur aide un peu en vous avertissant C4747 s'il détecte que DllMain n'est pas déclaré comme non géré:

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

Cependant, le compilateur ne générera aucun avertissement si DllMain appelle indirectement une autre fonction gérée, vous devez donc vous assurer que cela ne se produit jamais, sinon votre application pourrait se bloquer de manière aléatoire.


6

Appuyez sur ctr d + e puis dépensez le nœud des assistants de débogage gérés. Puis décoché le LoaderLock.

J'espère que ceci vous aidera.


Le raccourci est alt + d + x
Narayan

3
Le raccourci dépend en fait de la configuration que vous avez spécifiée à utiliser lors de la première exécution. La disposition des raccourcis C # est (Ctrl + D, E). (Vous pouvez également attribuer n'importe quelle combinaison de touches à cette fonction dans Options-> Environnement-> Clavier.)
Adam LS

5

Veuillez rappeler à ces utilisateurs de VS2017 que vous devez désactiver " aide d'exception " au lieu de " assistant d'exception " (avant VS2017) pour éviter une erreur de verrouillage du chargeur, dont le chemin d'accès est Debug-> Exception . Je viens de courir à ce problème et j'ai perdu 2 heures à chercher des solutions ...


Je n'ai pas "Exception" sous "Debug". J'ai VS2017 Community 15.8.4
Alex

@Alex, vérifiez le débogage -> Windows -> Paramètres d'exception, ou appuyez sur Ctrl + Alt + E
mistika

4

J'ai récemment eu cette erreur lors de la création d'une instance d'un objet COM écrit en code natif:

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

Cela a conduit à l'erreur décrite. Une exception "LoaderLock a été détecté" -Exception a été lancée.

J'ai surmonté cette erreur en créant l'instance d'objet dans un thread supplémentaire:

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'erreur peut se produire avec des objets distants (MarshalByRefObject), et cette solution ne fonctionne pas pour ceux-ci.
Matthieu

3

Je construis une DLL C ++ CLR (MSVS2015) qui doit effectuer des appels dans une DLL non managée et définir du code non managé. J'utilise #pragma managed et #pragma unmanaged pour contrôler le mode dans lequel il se trouve pour une zone donnée du code.

Dans mon cas, j'ai simplement mis #pragma non managé devant mon DllMain () et cela a résolu le problème. Il semblait penser que je voulais une version gérée de DllMain ().



2

Le chemin du paramètre dans mon instance de Visual Studio 2017 est Debug -> Windows -> Paramètres d'exception. La "fenêtre" des paramètres d'exception apparaissant dans le groupe d'onglets du bas (par opposition à une fenêtre séparée), m'a pris un certain temps pour la remarquer. Recherchez "loader".

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.