Loader-Sperrfehler


94

Ich baue auf C ++ - DLL auf, indem ich Code in C # schreibe.

Ich bekomme eine Fehlermeldung

LoaderLock wurde erkannt Meldung: Versuch einer verwalteten Ausführung innerhalb der OS Loader-Sperre. Versuchen Sie nicht, verwalteten Code in einer DllMain- oder Image-Initialisierungsfunktion auszuführen, da dies dazu führen kann, dass die Anwendung hängen bleibt.

Ich habe versucht herauszufinden, was dieser Fehler genau bedeutet, aber ich zeichne sinnlose Artikel und sage meistens, dass es nur eine Warnung ist, und ich sollte das in Visual Studio ausschalten. Die anderen Lösungen scheinen auf ITunes oder dieses Problem zurückzuführen zu sein, das beim Programmieren mit DirectX auftritt. Mein Problem ist mit keinem verbunden.

Kann jemand erklären, was das eigentlich bedeutet?


Ich habe das Gefühl, dass ich das gleiche Problem habe und was mich am meisten überrascht: Meine DLL ist nicht einmal verwalteter Code. Warum / wie soll sie verwalteten Code auf der (nicht vorhandenen) DllMain verwenden?
Sam

Ich habe diese Warnung erhalten, als ich versucht habe, den Inhalt eines Datasets im Debug-Modus anzuzeigen. Ich benutze c #, es passierte in einer normalen Windows-Form.
Soenhay

Da Sie die Ursache nicht herausfinden können (wie Sie in der oberen Antwort kommentiert haben), vermute ich, dass Sie eine DLL laden, die das Verbrechen begeht.
John Thoits

Antworten:


69

Sie müssen zum Menü Debug -> Ausnahmen gehen, die Managed Debugging-Assistenten öffnen, LoaderLock suchen und das Kontrollkästchen deaktivieren

http://goo.gl/TGAHV


21
Ja, auf diese Weise können Sie die Warnung deaktivieren. Aber selbst nach 2 Jahren habe ich nicht genau herausgefunden, warum es passiert ist.
Devdatta Tengshe

2
Dies geschah mit der Eröffnung eines alten Projekts in VS 2012
4imble

1
Ich bin bei dir @Kohan Ich habe auch ein älteres Projekt geöffnet und den Fehler bekommen. Ich habe die Ausnahme deaktiviert, möchte aber verstehen, was getan werden kann, um dies zu verhindern.
Pimenta

1
Wenn ich das Projekt als natives Debugging ausführe, mit allen Ausnahmen auf Standard (alle zurücksetzen), zeigt das Debug-Fenster <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - Der Versuch einer verwalteten Ausführung innerhalb der OS Loader-Sperre .... etc -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS zeigt dann während der CTOR-Sequenz mehrere Haltepunkte an. Das Deaktivieren der LoaderLock-Einstellung hilft nicht. Für mich musste ich die oberste MDA-Option (für ALLE MDA) ankreuzen, dann die oberste Option (für keine MDA) deaktivieren und dann erstellen + ausführen. Das hat bei meinem Kollegen nicht funktioniert.
GilesDMiddleton

17
Wenn Sie ein Update in VS2015 freigeben möchten, müssen Sie jetzt zu gehen Debug->Windows->Exception Settings. Der Rest ist der gleiche mitManaged Debugging Assistants \ LoaderLock
jxramos

52

Die allgemeine Idee der Loader-Sperre: Das System führt den Code in DllMain innerhalb einer Sperre aus (wie bei der Synchronisationssperre). Das Ausführen von nicht trivialem Code in DllMain erfordert daher "einen Deadlock", wie hier beschrieben .

Die Frage ist, warum Sie versuchen, Code in DllMain auszuführen? Ist es wichtig, dass dieser Code im Kontext von DllMain ausgeführt wird, oder können Sie einen neuen Thread erzeugen und den Code darin ausführen und nicht warten, bis der Code die Ausführung in DllMain abgeschlossen hat?

Ich glaube, dass das Problem mit Manged Code speziell darin besteht, dass das Ausführen von verwaltetem Code das Laden der CLR und dergleichen beinhalten kann und es nicht bekannt ist, was dort passieren könnte, was zu einem Deadlock führen würde ... Ich würde den Ratschlag "Deaktivieren dieser Warnung" nicht beachten "Wenn ich Sie wäre, weil die meisten Chancen stehen, dass Ihre Anwendungen unter bestimmten Szenarien unerwartet hängen bleiben.


4
Ich arbeite an einer Direct3D-Anwendung. Dies ist eine EXE. Ich sehe diesen Fehler jedoch immer noch. Irgendwelche Ideen, wie man das am besten behebt?
Agnel Kurian

18

UPDATE FÜR .NET 4.0 UND MEHR LETZTE RAHMEN

Dies ist eine alte Frage, die zum Zeitpunkt von .Net 2.0 gestellt wurde, als die Unterstützung für DLLs im gemischten Modus schwerwiegende Initialisierungsprobleme aufwies, die zu zufälligen Deadlocks neigten. Ab .NET 4.0 hat sich die Initialisierung von DLLs im gemischten Modus geändert. Jetzt gibt es zwei separate Initialisierungsstufen:

  1. Native Initialisierung, die am Einstiegspunkt der DLL aufgerufen wird und die native C ++ - Laufzeiteinrichtung und Ausführung Ihrer DllMain-Methode umfasst.
  2. Verwaltete Initialisierung, automatisch vom Systemlader ausgeführt.

Da Schritt 2 außerhalb der Loader-Sperre ausgeführt wird, gibt es keine Deadlocks. Die Details werden unter Initialisierung gemischter Baugruppen beschrieben .

Um sicherzustellen, dass Ihre Assembly im gemischten Modus von einer nativen ausführbaren Datei geladen werden kann, müssen Sie nur überprüfen, ob die DllMain-Methode als nativer Code deklariert ist. #pragma unmanagedkönnte hier helfen:

#pragma unmanaged

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

Es ist auch wichtig, dass jeder Code, den DllMain direkt oder indirekt aufruft, ebenfalls nicht verwaltet wird. Es ist sinnvoll, die von DllMain verwendete Funktionalität einzuschränken, damit Sie den gesamten von DllMain erreichbaren Code verfolgen und sicherstellen können, dass alles mit kompiliert wird #pragma unmanaged.

Der Compiler hilft ein wenig, indem er Ihnen C4747 warnt, wenn er feststellt, dass DllMain nicht als nicht verwaltet deklariert ist:

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

Der Compiler generiert jedoch keine Warnungen, wenn DllMain indirekt eine andere verwaltete Funktion aufruft. Sie müssen daher sicherstellen, dass dies niemals geschieht, da Ihre Anwendung sonst zufällig blockieren kann.


6

Drücken Sie Strg + E und dann den Knoten Verwaltete Debugging-Assistenten ausgeben. Deaktivieren Sie dann das LoaderLock.

Hoffe das wird dir helfen.


Die Abkürzung ist alt + d + x
Narayan

3
Die Verknüpfung hängt tatsächlich von der Konfiguration ab, die Sie für die erste Ausführung angegeben haben. Das C # -Verknüpfungslayout lautet (Strg + D, E). (Sie können dieser Funktion auch eine beliebige Tastenkombination unter Optionen-> Umgebung-> Tastatur zuweisen.)
Adam LS

5

Bitte erinnern Sie diese VS2017-Benutzer daran, dass Sie " Exception Helper " anstelle von " Exception Assistant " (vor VS2017) deaktivieren müssen, um einen Loader-Lock-Fehler zu vermeiden. Der Einstellungspfad lautet Debug-> Exception . Ich bin gerade auf dieses Problem gestoßen und habe 2 Stunden damit verbracht, nach Lösungen zu suchen ...


Ich habe keine "Ausnahme" unter "Debug". Ich habe VS2017 Community 15.8.4
Alex

@ Alex, suchen Sie nach Debug -> Windows -> Ausnahmeeinstellungen, oder drücken Sie Strg + Alt + E
Mistika

4

Ich habe kürzlich diesen Fehler beim Erstellen einer Instanz eines in nativem Code geschriebenen COM-Objekts erhalten:

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

Dies führte zu dem beschriebenen Fehler. Eine "LoaderLock wurde erkannt" -Ausnahme wurde ausgelöst.

Ich habe diesen Fehler überwunden, indem ich die Objektinstanz in einem zusätzlichen Thread erstellt habe:

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

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

Der Fehler kann bei Remotable-Objekten (MarshalByRefObject) auftreten, und diese Lösung funktioniert für diese nicht.
Matthieu

3

Ich erstelle eine C ++ CLR-DLL (MSVS2015), die eine nicht verwaltete DLL aufrufen und nicht verwalteten Code definieren muss. Ich verwende #pragma verwaltet und #pragma nicht verwaltet, um zu steuern, in welchem ​​Modus es sich für einen bestimmten Bereich des Codes befindet.

In meinem Fall habe ich einfach #pragma unmanaged vor mein DllMain () gestellt und dies hat das Problem gelöst. Es schien zu denken, ich wollte eine verwaltete Version von DllMain ().



2

Der Einstellungspfad in meiner Visual Studio 2017-Instanz lautet Debug -> Windows -> Ausnahmeeinstellungen. Das "Fenster" für die Ausnahmeeinstellungen wurde in der unteren Registerkartengruppe angezeigt (im Gegensatz zu einem separaten Fenster). Es dauerte eine Weile, bis ich es bemerkte. Suche nach "Lader".

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.