Partilhar via


loaderLock MDA |

Nota

Este artigo é específico do .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.

O loaderLock assistente de depuração gerenciado (MDA) deteta tentativas de executar código gerenciado em um thread que contém o bloqueio do carregador do sistema operacional Microsoft Windows. Qualquer execução desse tipo é ilegal porque pode levar a deadlocks e ao uso de DLLs antes de serem inicializadas pelo carregador do sistema operacional.

Sintomas

A falha mais comum ao executar código dentro do bloqueio do carregador do sistema operacional é que os threads serão bloqueados ao tentar chamar outras funções do Win32 que também exigem o bloqueio do carregador. Exemplos de tais funções são LoadLibrary, GetProcAddress, FreeLibrary, e GetModuleHandle. O aplicativo pode não chamar diretamente essas funções; o Common Language Runtime (CLR) pode chamar essas funções como resultado de uma chamada de nível superior como Load ou a primeira chamada para um método de invocação de plataforma.

Deadlocks também podem ocorrer se um thread estiver aguardando que outro thread comece ou termine. Quando um thread inicia ou termina a execução, ele deve adquirir o bloqueio do carregador do sistema operacional para entregar eventos às DLLs afetadas.

Finalmente, há casos em que chamadas para DLLs podem ocorrer antes que essas DLLs tenham sido inicializadas corretamente pelo carregador do sistema operacional. Ao contrário das falhas de deadlock, que podem ser diagnosticadas examinando as pilhas de todos os threads envolvidos no deadlock, é muito difícil diagnosticar o uso de DLLs não inicializadas sem usar este MDA.

Motivo

Assemblies C++ mistos gerenciados/não gerenciados criados para .NET Framework versões 1.0 ou 1.1 geralmente tentam executar código gerenciado dentro do bloqueio do carregador, a menos que um cuidado especial tenha sido tomado, por exemplo, vinculando com /NOENTRY.

Assemblies C++ mistos gerenciados/não gerenciados criados para o .NET Framework versão 2.0 são menos suscetíveis a esses problemas, tendo o mesmo risco reduzido que aplicativos que usam DLLs não gerenciadas que violam as regras do sistema operacional. Por exemplo, se o ponto de entrada de DllMain uma DLL não gerenciada chamar CoCreateInstance para obter um objeto gerenciado que foi exposto ao COM, o resultado será uma tentativa de executar código gerenciado dentro do bloqueio do carregador. Para obter mais informações sobre problemas de bloqueio do carregador no .NET Framework versão 2.0 e posterior, consulte Inicialização de assemblies mistos.

Resolução

No Visual C++ .NET 2002 e no Visual C++ .NET 2003, as DLLs compiladas com a /clr opção do compilador podem ser bloqueadas de forma não determinística quando carregadas, esse problema foi chamado de problema misto de carregamento de DLL ou bloqueio do carregador. No Visual C++ 2005 e posterior, quase todo o não-determinismo foi removido do processo de carregamento misto de DLL. No entanto, existem alguns cenários restantes para os quais o bloqueio do carregador pode (deterministicamente) ocorrer. Para obter uma descrição detalhada das causas e resoluções para os problemas de bloqueio do carregador restantes, consulte Inicialização de assemblies mistos. Se esse tópico não identificar o problema de bloqueio do carregador, você terá que examinar a pilha do thread para determinar por que o bloqueio do carregador está ocorrendo e como corrigir o problema. Observe o rastreamento de pilha para o thread que ativou este MDA. O thread está tentando chamar ilegalmente o código gerenciado enquanto mantém o bloqueio do carregador do sistema operacional. Você provavelmente verá uma DLL DllMain ou ponto de entrada equivalente na pilha. As regras do sistema operacional para o que você pode fazer legalmente de dentro de tal ponto de entrada são bastante limitadas. Estas regras impedem qualquer execução gerida.

Efeito no tempo de execução

Normalmente, vários threads dentro do processo serão bloqueados. É provável que um desses threads seja um thread responsável por realizar uma coleta de lixo, então esse impasse pode ter um grande impacto em todo o processo. Além disso, evitará quaisquer operações adicionais que exijam o bloqueio do carregador do sistema operacional, como carregar e descarregar assemblies ou DLLs e iniciar ou parar threads.

Em alguns casos incomuns, também é possível que violações de acesso ou problemas semelhantes sejam acionados em DLLs que são chamadas antes de serem inicializadas.

Saída

Este MDA relata que uma execução gerenciada ilegal está sendo tentada. Você precisa examinar a pilha do thread para determinar por que o bloqueio do carregador está ocorrendo e como corrigir o problema.

Configuração

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

Consulte também