[c#] 로더 잠금 오류

C #으로 코드를 작성하여 C ++ dll을 구축하고 있습니다.

오류가 발생합니다.

LoaderLock이 감지되었습니다. 메시지 : OS Loader 잠금 내에서 관리되는 실행을 시도 중입니다. DllMain 또는 이미지 초기화 함수 내에서 관리 코드를 실행하려고하면 응용 프로그램이 중단 될 수 있습니다.

이 오류가 정확히 무엇을 의미하는지 검색하려고 시도했지만 무의미한 기사를 그리는 중이며 대부분 경고 일 뿐이며 Visual Studio에서 해제해야합니다. 다른 솔루션은 ITunes 또는 DirectX로 프로그래밍 할 때 발생하는이 문제로 인한 것 같습니다. 내 문제는 둘 다와 관련이 없습니다.

아무도 이것이 실제로 무엇을 의미하는지 설명 할 수 있습니까?



답변

메뉴 디버그-> 예외로 이동하여 Managed Debugging Assistants를 열고 LoaderLock을 찾아 선택을 취소해야합니다.

http://goo.gl/TGAHV


답변

로더 잠금의 일반적인 개념 : 시스템은 잠금 내부에서 DllMain의 코드를 실행합니다 (동기화 잠금에서와 같이). 따라서 여기에 설명 된대로 DllMain 내에서 중요하지 않은 코드를 실행하는 것은 “교착 상태에 대한 요청” 입니다.

문제는 왜 DllMain 내에서 코드를 실행하려고합니까? 이 코드가 DllMain의 컨텍스트 내에서 실행되는 것이 중요합니까? 아니면 새 스레드를 생성하고 코드를 실행할 수 있으며 DllMain 내에서 코드 실행이 완료 될 때까지 기다리지 않을 수 있습니까?

특히 관리되는 코드의 문제는 관리되는 코드를 실행하는 데 CLR을로드하는 것과 관련이있을 수 있으며 교착 상태가 발생할 수있는 상황을 알 수 없다는 것입니다. “이 경고를 사용하지 않도록 설정하십시오.”라는 조언에주의하지 않을 것입니다. “대부분의 가능성 때문에 내가 당신이라면 일부 시나리오에서 응용 프로그램이 예기치 않게 중단되는 것을 알 수 있습니다.


답변

.NET 4.0 및 최신 프레임 워크 업데이트

이것은 혼합 모드 DLL에 대한 지원에 심각한 초기화 문제가 있고 임의의 교착 상태가 발생하기 쉬운 .Net 2.0 당시에 묻는 오래된 질문입니다. .Net 4.0부터 혼합 모드 DLL의 초기화가 변경되었습니다. 이제 두 가지 개별 초기화 단계가 있습니다.

  1. 기본 C ++ 런타임 설정 및 DllMain 메서드 실행을 포함하는 DLL의 진입 점에서 호출되는 기본 초기화.
  2. 시스템 로더에 의해 자동으로 실행되는 관리되는 초기화.

2 단계는 로더 잠금 외부에서 수행되므로 교착 상태가 없습니다. 자세한 내용은 혼합 어셈블리 초기화에 설명되어 있습니다.

혼합 모드 어셈블리를 네이티브 실행 파일에서로드 할 수 있는지 확인하려면 DllMain 메서드가 네이티브 코드로 선언되어 있는지 확인해야합니다. #pragma unmanaged여기에 도움이 될 수 있습니다.

#pragma unmanaged

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

DllMain이 직접 또는 간접적으로 호출 할 수있는 코드도 관리되지 않는 것도 중요합니다. DllMain에서 사용하는 기능 유형을 제한하여 DllMain에서 도달 할 수있는 모든 코드를 추적하고 모두 #pragma unmanaged.

컴파일러는 DllMain이 관리되지 않는 것으로 선언되지 않았 음을 감지하면 C4747을 경고하여 약간의 도움을줍니다.

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

그러나 DllMain이 다른 관리 함수를 간접적으로 호출하는 경우 컴파일러는 경고를 생성하지 않으므로 절대 발생하지 않도록해야합니다. 그렇지 않으면 응용 프로그램이 임의로 교착 상태가 될 수 있습니다.


답변

ctr d + e를 누른 다음 Managed Debugging Assistants Node를 확장합니다. 그런 다음 LoaderLock을 선택 취소했습니다.

이것이 당신을 도울 것입니다.


답변

친절하게 그 생각 나게 VS2017 사용자 는 사용 안 함 “을 필요 예외 도우미 대신”의 ” 예외 조수 입니다 설정 경로 로더 잠금 오류를 방지하기 위해 (VS2017 전)” Debug-> 예외 . 이 문제를 해결하고 해결책을 찾기 위해 2 시간을 낭비했습니다 …


답변

최근에 네이티브 코드로 작성된 COM-Object 인스턴스를 만드는 동안이 오류가 발생했습니다.

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

이로 인해 설명 된 오류가 발생했습니다. “LoaderLock이 감지되었습니다.”예외가 발생했습니다.

추가 스레드에서 개체 인스턴스를 만들어이 오류를 극복했습니다.

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

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


답변

관리되지 않는 DLL을 호출하고 관리되지 않는 코드를 정의해야하는 C ++ CLR DLL (MSVS2015)을 빌드 중입니다. 나는 #pragma managed와 #pragma unmanaged를 사용하여 주어진 코드 영역에 대한 모드를 제어합니다.

제 경우에는 단순히 DllMain () 앞에 #pragma unmanaged를 넣어 문제가 해결되었습니다. DllMain ()의 관리되는 버전을 원한다고 생각하는 것 같습니다.