Udostępnij za pośrednictwem


loaderLock MDA

Uwaga

Ten artykuł jest specyficzny dla programu .NET Framework. Nie ma zastosowania do nowszych implementacji platformy .NET, w tym .NET 6 i nowszych wersji.

Asystent loaderLock zarządzanego debugowania (MDA) wykrywa próby wykonania kodu zarządzanego w wątku, który przechowuje blokadę modułu ładującego systemu operacyjnego Microsoft Windows. Takie wykonanie jest nielegalne, ponieważ może prowadzić do zakleszczenia i używania bibliotek DLL przed ich zainicjowaniem przez moduł ładujący systemu operacyjnego.

Objawy

Najczęstszym błędem podczas wykonywania kodu wewnątrz blokady modułu ładującego systemu operacyjnego jest to, że wątki zakleszczą się podczas próby wywołania innych funkcji Win32, które również wymagają blokady modułu ładującego. Przykłady takich funkcji to LoadLibrary, , GetProcAddressFreeLibraryi GetModuleHandle. Aplikacja może nie wywoływać bezpośrednio tych funkcji; środowisko uruchomieniowe języka wspólnego (CLR) może wywoływać te funkcje w wyniku wywołania wyższego poziomu, takiego jak Load lub pierwszego wywołania metody wywołania platformy.

Zakleszczenia mogą również wystąpić, jeśli wątek czeka na uruchomienie lub zakończenie innego wątku. Po uruchomieniu lub zakończeniu wykonywania wątku musi on uzyskać blokadę modułu ładującego systemu operacyjnego, aby dostarczać zdarzenia do bibliotek DLL, których dotyczy problem.

Na koniec istnieją przypadki, w których wywołania do bibliotek DLL mogą wystąpić, zanim te biblioteki DLL zostały prawidłowo zainicjowane przez moduł ładujący systemu operacyjnego. W przeciwieństwie do błędów zakleszczenia, które można zdiagnozować, sprawdzając stosy wszystkich wątków zaangażowanych w impas, bardzo trudno jest zdiagnozować użycie niezainicjowanych bibliotek DLL bez użycia tego mdA.

Przyczyna

Mieszane zarządzane/niezarządzane zestawy języka C++ utworzone dla programu .NET Framework w wersji 1.0 lub 1.1 zwykle próbują wykonać kod zarządzany wewnątrz blokady modułu ładującego, chyba że została podjęta szczególna ostrożność, na przykład łączenie z /NOENTRY.

Mieszane zarządzane/niezarządzane zestawy języka C++ utworzone dla programu .NET Framework w wersji 2.0 są mniej podatne na te problemy, co aplikacje korzystające z niezarządzanych bibliotek DLL, które naruszają reguły systemu operacyjnego. Jeśli na przykład niezarządzany punkt wejścia biblioteki DLL DllMain wywołuje w CoCreateInstance celu uzyskania zarządzanego obiektu, który został uwidoczniony w modelu COM, wynikiem jest próba wykonania kodu zarządzanego wewnątrz blokady modułu ładującego. Aby uzyskać więcej informacji na temat problemów z blokadą modułu ładującego w programie .NET Framework w wersji 2.0 lub nowszej, zobacz Inicjowanie zestawów mieszanych.

Rozwiązanie

W programach Visual C++ .NET 2002 i Visual C++ .NET 2003 biblioteki DLL skompilowane przy /clr użyciu opcji kompilatora mogą niedeterministycznie zakleszczać podczas ładowania; ten problem został wywołany problemem z mieszanym ładowaniem bibliotek DLL lub blokadą modułu ładującego. W programie Visual C++ 2005 lub nowszym prawie cały niedeterminizm został usunięty z mieszanego procesu ładowania bibliotek DLL. Istnieje jednak kilka pozostałych scenariuszy, dla których może wystąpić blokada modułu ładującego (deterministycznie). Aby uzyskać szczegółowe informacje o przyczynach i rozwiązaniach pozostałych problemów z blokadą modułu ładującego, zobacz Inicjowanie zestawów mieszanych. Jeśli ten temat nie identyfikuje problemu z blokadą modułu ładującego, należy zbadać stos wątku, aby ustalić, dlaczego występuje blokada modułu ładującego i jak rozwiązać problem. Przyjrzyj się śladowi stosu wątku, który aktywował tę usługę MDA. Wątek próbuje nielegalnie wywołać kod zarządzany podczas przechowywania blokady modułu ładującego systemu operacyjnego. Prawdopodobnie na stosie pojawi się punkt wejścia bibliotek DLL DllMain lub równoważny. Reguły systemu operacyjnego dotyczące tego, co można legalnie zrobić z wnętrza takiego punktu wejścia, są dość ograniczone. Te reguły uniemożliwiają wykonywanie zarządzane.

Wpływ na środowisko uruchomieniowe

Zazwyczaj w procesie zakleszcza się kilka wątków. Jeden z tych wątków może być wątkiem odpowiedzialnym za wykonywanie odzyskiwania pamięci, więc ta impas może mieć duży wpływ na cały proces. Ponadto zapobiegnie to dodatkowym operacjom, które wymagają blokady modułu ładującego systemu operacyjnego, takich jak ładowanie i zwalnianie zestawów lub bibliotek DLL oraz uruchamianie lub zatrzymywanie wątków.

W niektórych nietypowych przypadkach istnieje również możliwość wyzwolenia naruszeń dostępu lub podobnych problemów w bibliotekach DLL, które są wywoływane przed ich zainicjowaniem.

Wyjście

Ta usługa MDA zgłasza, że jest podejmowana próba nielegalnego wykonania zarządzanego. Należy zbadać stos wątku, aby określić, dlaczego występuje blokada modułu ładującego i jak rozwiązać problem.

Konfigurowanie

<mdaConfig>
  <assistants>
    <loaderLock/>
  </assistants>
</mdaConfig>

Zobacz też