問題タブ [loaderlock]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - ローダロックエラー
C# でコードを記述して、C++ dll を構築しています。
エラーが表示されます
LoaderLock が検出されました メッセージ: OS ローダー ロック内でマネージ実行を試みています。アプリケーションがハングする可能性があるため、DllMain またはイメージ初期化関数内でマネージ コードを実行しようとしないでください。
このエラーが正確に何を意味するのかを検索しようとしましたが、無意味な記事を描いています。ほとんどの場合、それは単なる警告であり、Visual Studio でそれをオフにする必要があります。他の解決策は ITunes、または DirectX でのプログラミング時に発生するこの問題が原因のようです。私の問題はどちらにも接続されていません。
これが実際に何を意味するのか、誰か説明できますか?
.net - プログラム終了時の LoaderLock エラー
私は最近、純粋にアンマネージ コード (Visual Studio 6 でコンパイルされた C++ および VB6 コンポーネント) で開発されたアプリケーションの 1 つに .NET NLog ログ コンポーネントを統合しました。COM インターフェイスを介して NLog と通信する C++ アプリケーションが多数あります。
現時点ではすべて正常に動作していますが、プログラムの終了中に次のメッセージがポップアップすることに気付きました (VS6 で C++ コンポーネントをデバッグしている場合は出力ウィンドウに、VS 2005 経由で NLog をデバッグしている場合は IDE のプロンプトとして)。
LoaderLock が検出されました メッセージ: OS ローダー ロック内でマネージ実行を試みています。DllMain またはイメージ初期化関数内でマネージ コードを実行しようとしないでください。実行すると、アプリケーションがハングする可能性があります。
DllMain は次のとおりです。
私の推測では_Module.Term();
、いくつかの .NET 参照のリリースが含まれており (毎回インスタンス化してリリースする必要がないように、C++ クラスの 1 つで NLog オブジェクトへの参照を保持しています)、この警告がポップアップ表示されます。
私の質問: これは無視しても安全ですか? そうでない場合、適切な回避策は何ですか? (私が考えることができる最善の方法は、そのNLogオブジェクトへの参照をインスタンス化し、ログファイルに書き込みたいたびにそれを解放することです...最も洗練されたソリューションではありません)
c# - LoaderLock が検出され、警告をオフにしても機能しない
コンピューターのデフォルトのオーディオ録音デバイスからサウンドを取り込むアプリケーションを作成しようとしています。マネージド コードから DirectX にアクセスするコードを実行すると、次のエラーが発生します。
DLL 'C:\Windows\assembly\GAC\Microsoft.DirectX.DirectSound\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.DirectSound.dll' は、OS ローダー ロック内でマネージ実行を試みています。DllMain またはイメージ初期化関数内でマネージ コードを実行しようとしないでください。実行すると、アプリケーションがハングする可能性があります。
と
と
いずれも LoaderLock MDA がポップアップし、問題があることを通知します。この問題の解決策をインターネット (stackoverflow を含む) で探しましたが、ほとんどの人は警告をオフにするように言っているだけで、うまくいきません。警告をオフにすると、一般的な ApplicationException がスローされますが、これはさらに役に立ちません。この質問への回答も見ましたが、エラーの原因となっているコードを削除するように言われたため、役に立ちませんでした。「コードを修正してください」と言う人もいます。
私の質問は次のとおりです。
このエラーを発生させずに C# から (できれば管理された) DirectX コードを呼び出すにはどうすればよいですか?
編集:これは私が得るスタックトレースです:
c++ - ネイティブc++libに静的にリンクされたマネージC++dllでのローダーロックエラー
いくつかのマネージクラスを含むマネージc++dllがあり、dllに静的にリンクしているライブラリ内のネイティブc++コードを呼び出します。ただし、dllでRegAsm.exeを実行しようとすると、ツールは「登録したタイプがありません」と正しく報告しますが、ハングします。これはローダーロックの問題であり、RegAsmがロードしようとするとdllがハングすることは間違いありません。Visual Studio 2008ExpressEditionを使用しています。
ネイティブコードをdllに配置する場合はすべて正常に機能しますが、ライブラリから静的にリンクする場合は機能しないことに戸惑います。この投稿がこの質問に似ていることは承知していますが、dllにDllMainがありません。DllMainからMSILコードを実行するリスクはありません。また、個々のファイルに/clrを設定するというアドバイスに従うことは役に立ちませんでした。
/ NOENTRYを使用してdllをコンパイルすると、ロックの問題は修正されますが、Type initializer for <Module> threw exception
例外が発生してアプリケーションが破損するため、.NET2003でのみ推奨されるようです。
静的メンバーの初期化が原因である可能性があると思われますが、静的ライブラリでMSILにコンパイルされるのはなぜ私を超えているのでしょうか。
明確にするために:dllでRegAsm.exeを実行する必要はありませんが、ローダーロックの問題のチェックとして使用しています。実際には、COMに表示されるクラスをほとんど実装していないac#アセンブリでdllを使用しているため、そのクラスでCOM登録を行う必要があります。最後に、COM相互運用機能の登録中にC#IDEがクラッシュし、'R6033 c ++ランタイムエラーが報告されます:ネイティブコードの初期化中にこのアセンブリのMSILコードを使用しようとしました。これは、アプリケーションにバグがあることを示しています。これは、ネイティブコンストラクターまたはDllMainからMSILコンパイル済み(/ clr)関数を呼び出した結果である可能性があります。
問題は解決しましたが、不明な点がいくつかあり、興味があります。
動作が停止したときに、静的にリンクされたlibのヘッダーファイルに2つの静的変数が追加されていることに気付きました。これは、次のようになります。
初期化を.cppファイルに移動する(およびに変更static
するextern
)と、ローダーのロックが修正されます。イニシャライザがMSILにコンパイルされる理由を誰かが指摘できますか?
修正前は、マネージdllからヘッダーファイルを#includeしただけで、問題なく動作しました。しかし、ヘッダーを含め、libにもリンクしていると、うまくいきませんでした。libも内部でヘッダーを使用するので、静的変数の2つのインスタンスになりましたか?いずれにせよ、なぜMSILコードの実行に関する苦情があるのでしょうか。
今はうまくいきますが、どんな洞察も歓迎します。
winapi - GetModuleHandle の実装
私はそうする必要があるDllMain()
ので、ローダーロックが保持されます。GetModuleHandle()
ローダー ロック [ページ #6] も使用しているため、デッドロックが発生することを読みました。
GetModuleHandle() はどのように実装できますか? いくつかのコードはプラスになります。
更新:私はSetWindowsHookEx
WinXPでのみ使用しているため。コメントでアドバイスを受けて、簡単な方法で、最初にコールバックが呼び出されたときに GetModuleHandle() を使用します。
winapi - getmodulefilename は何をブロックする可能性がありますか?
マルチスレッドアプリケーションがあります。ワーカー スレッドの 1 つは、ログ記録のために GetModuleFilename を呼び出します。GetModuleFilename を呼び出す前にワーカー スレッドがロックを保持し、永久にブロックするデッドロックが発生しました。
このロック内から GetModuleFilename 呼び出しを削除することはできますし、削除しましたが、デッドロックがどのように発生するかについてはまだ非常に関心があります。
オンラインで読書をする: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx
GetModuleFilename がローダーロックを取得するようです。これは、デッドロックのかなり良い候補のように思えました。
ただし、通常、ローダーロック内のスレッドは、上記のリンクのように dllmain を除いて、独自のコードを実行していません。
dll_thread_attach または detach は、ローダーロックと、作成または破棄される別のワーカースレッドで呼び出される可能性がありますが、これが使用しているロックを取得しようとする方法はわかりません。
また、メイン スレッドが GetModuleFilename スレッドが保持しているロックを取得しようとし、3 番目のスレッドがローダーロックを保持し、sendmessage などをメイン スレッドでブロックしている可能性もあります。ここでも、これが発生する状況は見つかりませんでした。
私が疑わしい他のスレッドの 1 つは、com オブジェクトを使用するスレッドです。スレッドは最初に coinitialize を呼び出すため、シングル スレッド アパートメントにする必要があります。ここでローダーロックと相互作用する可能性はありますか?
とにかく、このデッドロックが発生する正確な方法を特定できていません。だから私はいくつかのアイデア、またはローダーロックが取得されている他のケースに関する詳細情報、およびブロックされる可能性のあるローダーロック内でコードが実行される他のシナリオがあるかどうかを期待しています。
ありがとう。
wpf - VB.NET 2008 でのローダー ロック エラー (Windows XP のみ?)
Windows XP でアプリケーション (WPF、VB.net 2008) を実行すると、奇妙な Windows エラーが発生します。エラーとデバッグが発生したマシンにVS2008をインストールしたとき。ローダー ロックの例外が発生したので、デバッグに移動して削除しました。ただし、マシンにインストールしてもエラーが発生します。
アプリケーションのインストール時にローダー ロック例外を削除する方法はありますか。それが最善の解決策ではないことは理解していますが、これは ReportViewer で WindowsElementHost を開始したときにのみ発生するようで、これが問題を引き起こしているため、他に何をすべきかわかりません。
2003年と同様に、XPのすべてのバージョンにその問題があります。
Windows 7 および Vista では、デバッグ中およびインストールされた製品中にそのエラーが発生することはありません。同じことが 2008 および 2008R2 にも当てはまります。
c++ - ダイナミック リンク ライブラリのベスト プラクティス - デッドロックを回避するには?
バックグラウンド
Dynamic-Link Library Best Practicesを読み、 DllMainでできることとできないことを理解しました。
ここで、多くのプロジェクトを含む Visual Studio 2013 ソリューションがあるとします。各プロジェクトは、異なるバイナリ/lib ファイルを生成します。
すべてのプロジェクトで使用される lib ファイルを生成するユーティリティ プロジェクトがあるとします。
ここで、このユーティリティ プロジェクトは、たとえば、上記のリンクに基づくLoadLibrary 関数を呼び出すいくつかの汎用関数を定義する場合があります。 DllMain 内から次のタスクを実行しない
質問
関数のスコープ内で呼び出されているため、特定の API を使用できないことを「知っている」汎用関数を実装するにはどうすればよい
DllMain
ですか?Windowsローダーロックにアクセスして、特定の呼び出しを無効にしたり、ロックされている場合は関数のアルゴリズムを変更したりすることはできますか?
例
プロジェクトユーティリティ
プロジェクトA
プロジェクトB
関数の呼び出しGetUserName()
は ではまったく問題ありませんがProject B
、 では禁止されています。Project A
そのような場合を回避するように、mu ソリューションをスマートにしたいと考えています。
理論的アプローチ
if( IsLoaderLocked() )
もちろん、これは実際のコードではありません。「危険な」API を呼び出す前に評価したい条件の例です。
.net - C++/CLI アセンブリでの例外 0xC0020001
The string binding is invalid.
これは、いくつかの C++ ネイティブ スタティック ライブラリと DLL を参照する代わりに、C++/CLI DLL を使用する C# EXE で構成されるかなり複雑なアプリケーションをシャットダウンしようとすると発生します。(VS2013 と Boost 1.55 を使用しています。)
この問題が発生するのは、_atexit
(DLL の終了時に) が_t2m@???__Fep@?1???$get_static_exception_object@Ubad_exception_@exception_detail@boost@@@exception_detail@boost@@YA?AVexception_ptr@1@XZ@YAXXZ@?A0x8b93c95f@@YAXXZ
ネイティブからマネージへのサンクである を呼び出そうとしているためです。CLR はおそらくその時点で既にシャットダウンされています。
私の主な質問は、管理されたサンクがネイティブの終了ハンドラーに登録されている理由です。定義上、機能しないためです。関連する質問は、なぜこの型に対してマネージ サンクが生成されるのかということです。私が知る限り、#include
この型を参照できるものはすべて、コンパイルされていない/clr
ファイルか、#pragma unmanaged
ブロック内の/clr
いずれかにあるからです。コンパイルされたファイルであるため、管理されたバージョンはまったく存在しないはずです。( のヘルプで#pragma managed
は、インスタンス化のポイントではなく、テンプレートが管理されているかどうかを定義するのは定義のポイントであると述べています。)
おそらく私はこれについて間違ってい#include
ますが、ファイル内のネイティブ型 (非/clr
ファイルに実装されている)のヘッダー ファイルを ing するときは、ODR の問題を防ぐためにブロックに/clr
ラップする必要があると常に想定していました。unmanaged
質問 (私はここで読んだことを覚えていますが、今ではリンクを見つけることができません) は、解決策はすべてのプラグマを削除し、コンパイラにそれを理解させることであることを示唆しています。ただし、それを行うとManaged Debugging Assistant 'LoaderLock' has detected a problem
、起動時に発生します。(コール スタックは、C++/CLI DLL をロードする原因となる C# コードを指しているだけなので、まったく役に立ちません。)
この質問は、テンプレートのインスタンス化に関するコンパイラのバグがあることを示唆しています。これがテンプレートであることを考えるとget_static_exception_object
、これはもっともらしいように思えますが、回避する方法がわかりません。
同様に誤って登録された別の関数は ですが_t2m@???__FstrMgr@?1??GetInstance@CAtlStringMgr@ATL@@SAPAUIAtlStringMgr@2@XZ@YAXXZ@@YAXXZ
、これはテンプレートではないため、ニシンである可能性があります。
(私はより小さな例で問題を再現しようとしましたが、まだできていません。明らかに、私が気付いていないトリガーがあります。)