loaderLock MDA
Kommentar
Den här artikeln är specifik för .NET Framework. Det gäller inte för nyare implementeringar av .NET, inklusive .NET 6 och senare versioner.
Den loaderLock
hanterade felsökningsassistenten (MDA) identifierar försök att köra hanterad kod på en tråd som innehåller Microsoft Windows-operativsystemets inläsningslås. Alla sådana körningar är olagliga eftersom det kan leda till dödlägen och användning av DLL:er innan de har initierats av operativsystemets inläsare.
Symtom
Det vanligaste felet vid körning av kod i operativsystemets lastarlås är att trådarna kommer att blockeras vid försök att anropa andra Win32-funktioner som också kräver lastarlåset. Exempel på sådana funktioner är LoadLibrary
, GetProcAddress
, FreeLibrary
och GetModuleHandle
. Programmet kanske inte anropar dessa funktioner direkt. common language runtime (CLR) kan anropa dessa funktioner som ett resultat av ett anrop på högre nivå som Load eller det första anropet till en plattformsanropsmetod.
Dödlägen kan också inträffa om en tråd väntar på att en annan tråd ska starta eller slutföras. När en tråd startar eller slutför körningen måste den hämta operativsystemets inläsningslås för att leverera händelser till berörda DLL:er.
Slutligen finns det fall där anrop till DLL:er kan inträffa innan dessa DLL:er har initierats korrekt av operativsystemets inläsare. Till skillnad från dödlägesfelen, som kan diagnostiseras genom att undersöka staplarna för alla trådar som ingår i dödläget, är det mycket svårt att diagnostisera användningen av onitialiserade DLL:er utan att använda denna MDA.
Orsak
Blandade hanterade/ohanterade C++-sammansättningar som skapats för .NET Framework-versionerna 1.0 eller 1.1 försöker vanligtvis köra hanterad kod i inläsningslåset om inte särskild försiktighet har vidtagits, till exempel länkning med /NOENTRY.
Blandade hanterade/ohanterade C++-sammansättningar som skapats för .NET Framework version 2.0 är mindre känsliga för dessa problem, med samma minskade risk som program som använder ohanterade DLL:er som bryter mot operativsystemets regler. Om till exempel en ohanterad DLL-startpunkt anropar CoCreateInstance
för att hämta ett hanterat objekt som har exponerats för COM, är resultatet ett försök att köra hanterad kod i inläsningslåsetDllMain
. Mer information om problem med inläsningslås i .NET Framework version 2.0 och senare finns i Initiering av blandade sammansättningar.
Åtgärd
I Visual C++ .NET 2002 och Visual C++ .NET 2003 kan DLL:er som kompilerats med kompileringsalternativet /clr
icke-deterministiskt dödläge när de läses in. Det här problemet kallades för blandat DLL-inläsnings- eller inläsningslås. I Visual C++ 2005 och senare har nästan all icke-determinism tagits bort från den blandade DLL-inläsningsprocessen. Det finns dock några återstående scenarier där inläsningslåset (deterministiskt) kan inträffa. En detaljerad beskrivning av orsakerna och lösningarna för återstående problem med inläsningslås finns i Initiering av blandade sammansättningar. Om det ämnet inte identifierar problemet med lastarlåset måste du undersöka trådens stack för att avgöra varför lastarlåset inträffar och hur problemet ska åtgärdas. Titta på stackspårningen för den tråd som har aktiverat denna MDA. Tråden försöker anropa den hanterade koden olagligt medan operativsystemets inläsningslås hålls kvar. Du kommer förmodligen att se en DLL DllMain
eller motsvarande startpunkt i stacken. Operativsystemets regler för vad du lagligt kan göra inifrån en sådan startpunkt är ganska begränsade. Dessa regler utesluter alla hanterade körningar.
Effekt på körningen
Vanligtvis kommer flera trådar i processen att blockeras. En av dessa trådar är sannolikt en tråd som ansvarar för att utföra en skräpinsamling, så det här dödläget kan ha stor inverkan på hela processen. Dessutom förhindrar det ytterligare åtgärder som kräver operativsystemets lastarlås, som att läsa in och ta bort sammansättningar eller DLL:er och starta eller stoppa trådar.
I vissa ovanliga fall är det också möjligt att åtkomstöverträdelser eller liknande problem utlöses i DLL:er som anropas innan de har initierats.
Output
Denna MDA rapporterar att en olaglig hanterad körning försöker utföras. Du måste undersöka trådens stack för att avgöra varför inläsningslåset inträffar och hur problemet ska åtgärdas.
Konfiguration
<mdaConfig>
<assistants>
<loaderLock/>
</assistants>
</mdaConfig>