3

ほとんどの場合、非常にうまく機能する大規模な Compact Frameworks V2.0 アプリケーションがあります。特定のデバイスでは、約 1 日に 1 回、標準の管理された Try/Catch ブロックではキャッチされないネイティブ エラー 0xC0000005 をユーザーが受け取ります。

私のアプリケーションは、一定の間隔で ASMX 呼び出しを介してサーバーと同期します。この問題は、同期中に発生するようです。同期時に発生する ASMX 呼び出しに加えて、かなりのビジネス ロジックがありますが、その 98% はマネージ コードです。私はすべての P/Invokes とアプリケーションのネイティブ C++ ライブラリを確認しましたが、この時点で、そこに問題がないことを約 95% 確信しています。

これは特定のデバイスでのみ発生し、非常にまれに (1 日に 1 回未満) 発生するため、特定するのは非常に困難です。コードを実装しましたが、アプリケーション内のランダムな場所で発生しているように見えるため、何かがメモリを破損していると思われます。

これをさらにトラブルシューティングする方法についての考えをいただければ幸いです。

4

2 に答える 2

5

0xC0000005 はアクセス違反であるため、何かがアクセス権のないアドレスから読み書きしようとしています。これらは見つけるのが非常に難しい傾向があり、経験は最高のツールの 1 つです (Platform Builder のデバッガーも非常に役立ちますが、それはデバッグのまったく別の方法であり、おそらく持っていない、または既に持っている経験が必要です)それを試してみました)。ロギングは、サブトラクティブ コーディングほど有用ではない傾向があることがわかりました。可能な場合は、モック マネージド コールを使用して P/invoke コールを削除します。

マネージド アプリでのアクセス違反は、通常、次のいずれかの理由で発生します。

  • 管理対象オブジェクトへのハンドルを渡すネイティブ API を P/Invoke し、ネイティブ API がそのハンドルを使用します。ネイティブ API の実行中にコレクションとコンパクションを取得すると、マネージド オブジェクトが移動し、ポインターが無効になる場合があります。
  • 渡したサイズよりも小さすぎるか小さすぎるバッファーで何かを P/Invoke すると、API が読み取りまたは書き込みをオーバーランします。
  • P/Invoke 呼び出しに渡すポインター (IntPtr など) が無効 (-1 または 0) であり、ネイティブが使用前にチェックしていない
  • ネイティブ呼び出しを P/Invoke すると、ネイティブ コードがメモリ (通常は仮想) を使い果たし、失敗した割り当てと無効なアドレスへの読み取り/書き込みをチェックしていません。
  • 初期化されていない、または何らかの方法で既にファイナライズされ収集されたオブジェクトを指している GCHandle を使用します (したがって、オブジェクトを指しているのではなく、オブジェクトがあった場所のアドレスを指しています)。
  • あなたのアプリは、スリープ/ウェイクによって無効になったものへのハンドルを使用しています。これはより難解ですが、確かに起こります。たとえば、ストレージ カードからアプリケーションを実行している場合、アプリ全体が RAM に読み込まれるわけではありません。使用中のピースは、実行のために要求ページインされます。これはすべて順調です。デバイスの電源をオフにすると、ドライバーはすべてシャットダウンします。電源を入れ直すと、多くのデバイスは単純にストレージ デバイスを再マウントします。アプリがより多くのプログラムでページを要求する必要がある場合、アプリは元の場所になくなり、機能しなくなります。マウントされたストア上のデータベースでも同様の動作が発生する可能性があります。データベースへの開いているハンドルがある場合、スリープ/ウェイク サイクルの後、接続ハンドルが有効でなくなる可能性があります。

ここで、これらのほとんどすべてが P/Invoke であり、それは偶然ではないという傾向に気付くでしょう。マネージ コードだけでこれを行うのは非常に困難です。

于 2008-12-31T14:51:38.517 に答える
1

私のネイティブ C++ 例外処理には非同期例外が含まれていなかったため、アクセス違反の例外をキャッチしていませんでした。

これは私の問題には役立つかもしれないし、そうでないかもしれませんが、他の人には役立つかもしれません。

このリンクに記載されているように /EHa スイッチを使用すると、次の種類の例外をキャッチできます。

http://msdn.microsoft.com/en-us/library/1deeycx5.aspx

于 2008-12-31T19:09:06.390 に答える