ローダーロックエラー


95

C#でコードを記述して、C ++ dllを構築しています。

私はエラーを出して言った

LoaderLockが検出されましたメッセージ:OSローダーロック内で管理された実行を試みています。DllMainまたはイメージ初期化関数内でマネージコードを実行しようとしないでください。実行すると、アプリケーションがハングする可能性があります。

私はこのエラーが正確に何を意味するかを調べてみましたが、私は無意味な記事を描いています。ほとんどの場合それは単なる警告であり、Visual Studioでそれをオフにする必要があります。他の解決策は、iTunesまたはDirectXでプログラミングするときに発生するこの問題が原因であるようです。私の問題はどちらにも関係していません。

誰かが説明できますか、これは実際にはどういう意味ですか?


私はあなたと一緒に感じ、同じ問題が発生しましたが、最も驚いたのは、dllがマネージコードでさえないため、(存在しない)DllMainでマネージコードを使用する理由/方法は何ですか?
Sam

デバッグモードでデータセットの内容を表示しようとしたときに、この警告が表示されました。私はc#を使用していますが、通常のWindowsフォームで発生しました。
Soenhay、2015年

原因を突き止めることができないので(トップの回答でコメントしたように)、ロードしているDLLが犯罪を犯しているのではないかと思います。
John Thoits

回答:


70

メニューのデバッグ->例外に移動し、マネージデバッグアシスタントを開き、LoaderLockを見つけてチェックを外す必要があります

http://goo.gl/TGAHV


21
はい、これは警告をオフにする方法です。しかし、2年経っても、なぜそれが起こったのか正確にはわかりませんでした。
Devdatta Tengshe 2010年

2
これは、VS 2012で古いプロジェクトを開いているときに起こりました
4imble

1
私は@Kohanと一緒にいます古いプロジェクトを開いてエラーが発生しました。例外を無効にしましたが、これを防ぐために何ができるかを理解したいと思います。
ピメンタ

1
プロジェクトをネイティブデバッグとして実行し、すべての例外をデフォルト(すべてリセット)で実行すると、デバッグウィンドウに<mda:msg xmlns:mda = " schemas.microsoft.com/CLR/2004/10/mda "> <!- -OSローダーロック内で管理された実行を試行しています...など-> <mda:loaderLockMsg break = "true" /> </ mda:msg>次に、VSはCTORシーケンス中に複数のブレークポイントを表示します。LoaderLock設定をオフにしても効果はありません。私にとっては、最上位のMDAオプション(すべてのMDAの場合)にチェックマークを付け、次に最上位のオプション(MDAなしの場合)のチェックを外してから、ビルド+実行する必要がありました。これは私の同僚にとってはうまくいきませんでした。
GilesDMiddleton 2014年

17
VS2015のアップデートを共有したかったので、にアクセスする必要がありますDebug->Windows->Exception Settings。残りは同じですManaged Debugging Assistants \ LoaderLock
jxramos

52

ローダーロックの一般的な考え方:システムはDllMainのコードをロック内で実行します(同期ロックの場合と同様)。したがって、ここで説明するように、DllMain内で重要なコードを実行すると、「デッドロックを要求する」ことになります

問題は、なぜDllMain内でコードを実行しようとしているのか、です。このコードがDllMainのコンテキスト内で実行されることが重要ですか、それとも新しいスレッドを生成してコードを実行でき、DllMain内でコードの実行が完了するのを待たないのですか?

マネージコードの問題は、具体的には、マネージコードの実行にCLRの読み込みなどが含まれる可能性があり、そこで何が起こり、デッドロックが発生するかわからないことです...「この警告を無効にする」のアドバイスには注意しません。 「もし私があなただったら、いくつかのシナリオでは、アプリケーションが予期せずハングする可能性が高いからです。


4
Direct3Dアプリケーションに取り組んでいます。これはEXEです。ただし、まだこのエラーが表示されます。これを最もよく修正する方法はありますか?
Agnel Kurian、

18

.NET 4.0以降のフレームワークの更新

これは、.Net 2.0の時点で尋ねられた古い質問です。混合モードDLLのサポートに重大な初期化の問題があり、ランダムデッドロックが発生する傾向がありました。.Net 4.0以降、混合モードDLLの初期化が変更されました。これで、初期化の2つの別個の段階があります。

  1. DLLのエントリポイントで呼び出されるネイティブ初期化。これには、ネイティブC ++ランタイムのセットアップとDllMainメソッドの実行が含まれます。
  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が他のマネージ関数を間接的に呼び出した場合、コンパイラーは警告を生成しないため、発生しないようにする必要があります。そうしないと、アプリケーションがランダムにデッドロックする可能性があります。


6

ctr d + eを押してから、Managed Debugging Assistantsノードを拡張します。次に、LoaderLockのチェックを外しました。

これがお役に立てば幸いです。


ショートカットはalt + d + xです
ナラヤン2013年

3
ショートカットは実際には、最初の実行時に使用するように指定した構成によって異なります。C#のショートカットレイアウトは(Ctrl + D、E)です。(また、オプション
Adam LS

5

ローダーのロックエラーが発生しないようにするには、「例外アシスタント」ではなく「例外ヘルパー」を無効にする必要があることをVS2017ユーザーに思い出してください。この設定パスはDebug-> Exceptionです。ちょうどこの問題にぶつかり、解決策を探すために2時間を無駄にした...


「デバッグ」の下に「例外」がありません。私はVS2017コミュニティ15.8.4
Alex

@ Alex、Debug-> Windows-> Exception Settingsを確認するか、Ctrl + Alt + Eを押します
mistika

4

ネイティブコードで記述されたCOMオブジェクトのインスタンスを作成しているときに、最近このエラーが発生しました。

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

これにより、前述のエラーが発生しました。「LoaderLock was detected」-例外がスローされました。

追加のスレッドでオブジェクトインスタンスを作成することで、このエラーを克服しました。

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

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

エラーはRemotableオブジェクト(MarshalByRefObject)で発生する可能性があり、このソリューションはそれらに対しては機能しません。
Matthieu

3

アンマネージDLLを呼び出してアンマネージコードを定義する必要があるC ++ CLR DLL(MSVS2015)を構築しています。#pragma managedおよび#pragma unmanagedを使用して、コードの特定の領域でのモードを制御します。

私の場合、私は単に#pragma unmanagedを私のDllMain()の前に置くだけで問題が解決しました。DllMain()のマネージドバージョンが必要だと思っているようです。



2

私のVisual Studio 2017インスタンスの設定パスは、デバッグ-> Windows->例外設定です。例外設定の「ウィンドウ」が(別のウィンドウではなく)下部のタブグループに表示され、気づくまでに少し時間がかかりました。「ローダー」を検索します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.