2

私は必死に近づいています.. C# とかなりの p/Invoking を使用して、Windows Mobile 6.1 用のフィールド サービス アプリケーションを開発しています。(50個くらいのネイティブ関数を参照していると思います)

通常の状況では、これは問題なく行われますが、GC に負荷をかけ始めると、厄介な 0xC0000005 エラーが発生します。魔女は捕まえられないようです。私のテストでは、ダイアログ フォームをすばやく閉じたり開いたりしています (フォームはネイティブ関数を使用していましたが、テストのためにこれらをコメント アウトしました)。私のアプリケーションのエラー。

私のコードは try-catch を使用Application.Run(masterForm);してイベントにフックしCurrentDomain.UnhandledExceptionますが、アプリケーションは依然としてクラッシュします。デバッガーをアタッチしても、例外が発生すると、ビジュアルスタジオは「デバイスへのリモート接続が失われました」と言うだけです..

管理された環境で例外をキャッチできなかったため、Error Reporter のログ ファイルを調べてみました。しかし、これは意味がありません。エラーについて唯一一貫しているのは、エラーが発生したアプリケーションです。

アプリケーションが発生するスレッドは不明です。エラーが発生するモジュールは時々異なります (application.exe、WS2.dll、netcfagl3_5.dll、および mscoree3_5.dll を見たことがあります)。エラー コードもわかりません。常に同じではありません。(ほとんどの場合は 0xC0000005 ですが、0X80000002 エラーも見たことがあります。これは最初のバイトを説明する警告ですか?)

バグトラップを使用してデバッグを試みましたが、奇妙なことに、これは同じエラー コード (0xC0000005) でクラッシュします。Visual Studioでkdmpファイルを開こうとしましたが、エラーが発生したときに逆アセンブラーコードしか表示されないため、これを理解できないようです(適切な.pbbファイルがない限り、. 't)。WinDbg についても同様です。

長い話を簡単に言うと、率直に言って、このエラーをどこで探すべきかについての手がかりが1つもありません。いくつかのコードを提供できてうれしいですが、現時点ではどの部分を提供すればよいかわかりません..

どんな助けでも大歓迎です!

[2010 年 5 月 3 日編集]

Hans へのコメントでわかるように、すべての P/Invokes のコメントを外した後、プログラム全体を再テストしましたが、問題は解決しませんでした。できるだけ少ないコードでエラーを再現しようとしましたが、最終的にマルチスレッド アクセスがすべての問題を引き起こしているようです。

私のアプリケーションには、指/フリックスクロールリストとして機能するユーザーコントロールがあります。このコントロールでは、リスト内の各項目のビットマップをキャンバスとして使用します。このキャンバスでの描画は別のスレッドで処理され、このスレッドを無効にすると、エラーが消えたように見えます..これについてさらにテストを行い、結果をここに投稿します.

4

2 に答える 2

4

この例外をキャッチすることはオプションではありません。これは、スレッドが被る最悪の種類の心臓発作であり、CPU が深刻な問題を検出したため、コードの実行を続行できません。これは常に、アンマネージ コードの誤動作が原因で発生します。プログラム内で大量のアンマネージ コードが実行されているようです。アンマネージ コードのデバッグに集中して、目的を達成する必要があります。

AVの最も一般的な2つの原因は以下のものです。

  • ヒープの破損。アンマネージ コードがヒープにデータを不適切に書き込み、ヒープの構造的整合性を破壊しています。通常、割り当てられたメモリ ブロックの境界のオーバーフローが原因で発生します。または、解放された後にヒープ ブロックを使用します。診断が非常に難しく、損傷が発生してからずっと後に例外が発生します。

  • スタックの破損。最も一般的な原因は、スタックに割り当てられた配列の境界のオーバーフローです。これにより、スタック上の他の変数の値が上書きされたり、関数の戻りアドレスが破壊されたりする可能性があります。診断が少し簡単で、よく繰り返す傾向があり、すぐに効果があります。副作用の 1 つは、損傷が発生した直後に、デバッガーがコール スタックを表示できなくなることです。

ヒープの破損は可能性が高く、難しいものです。これは通常、ヒープの整合性を監視するデバッグ アロケーターを使用してデバッグ ビルドでコードをデバッグすることによって対処されます。<crtdbg.h>ヘッダーは 1 つを提供します。これは保証されたアプローチではありません。Release ビルドで頭をもたげるだけの非常に厄介な Heisenbugs を持つことができます。その場合、慎重なコード レビュー以外に利用できるオプションはほとんどありません。頑張ってください、あなたはそれを必要とします。

于 2010-04-28T12:32:24.243 に答える
0

Interlocked による例外であることが判明しました。

_drawThreadIsRunning私のコードには、描画スレッドが実行されているときに 1 に設定され、それ以外の場合は 0 に設定される整数があります。Interlocked を使用してこの値を設定します。

if (Interlocked.Exchange(ref _drawThreadIsRunning, 1) == 0) { /* run thread */ }

この行を変更するとすべてが機能するため、どこかにスレッドセーフに問題があるようですが、わかりません。(つまり、それを理解するためにこれ以上時間を無駄にしたくない)

助けてくれてありがとう!

于 2010-05-25T14:14:46.270 に答える