Windows Mobileデバイスで非常に断続的なアクセス違反をトラブルシューティングするためのテクニックは何ですか?
-
03-07-2019 - |
質問
ほとんどの場合、非常にうまく機能する大規模なCompact Frameworks V2.0アプリケーションがあります。特定のデバイスで1日に1回程度、ユーザーは標準の管理Try / Catchブロックでキャッチされないネイティブエラー0xC0000005を受け取ります。
私のアプリケーションは、一定の間隔でASMX呼び出しを介してサーバーと同期します。問題は同期中に発生するようです。同期時に発生するASMX呼び出しに加えて、かなりのビジネスロジックがありますが、その98%はマネージコードです。私はすべてのP / InvokesとアプリケーションのネイティブC ++ライブラリをレビューしましたが、この時点で、問題がどこにあるかは約95%確信しています。
これは特定のデバイスでのみ発生し、非常にまれ(1日に1回未満)であるため、隔離することは非常に困難です。私は自分のコードを誤解し、アプリケーション内のランダムな場所で発生するように見えるので、何かがメモリを破損していると思われます。
これをさらにトラブルシューティングする方法についてのご意見をいただければ幸いです。
解決 2
ネイティブC ++例外処理には非同期例外が含まれていなかったため、アクセス違反例外をキャッチしていませんでした。
これは私の問題には役立つかもしれませんが、他の人には役立つかもしれません。
このリンクに記載されている/ EHaスイッチを使用すると、次のタイプの例外をキャッチできます。
他のヒント
0xC0000005はアクセス違反であるため、アクセス権のないアドレスに対して何かが読み取りまたは書き込みを試みています。これらは見つけるのが非常に難しい傾向があり、経験は最高のツールの1つです(Platform Builderのデバッガも非常に役立ちますが、それはデバッグのまったく別の道であり、おそらく持っていないか、すでに経験している経験が必要ですそれを試してみました)。ロギングは、サブトラクティブコーディングよりも有用性が低い傾向があることに気付きました-可能な限り、モック管理呼び出しでP / invoke呼び出しを削除します。
管理対象アプリでのアクセス違反は通常、次のいずれかの理由で発生します。
- 管理対象オブジェクトにハンドルを渡すネイティブAPIをP /呼び出し、ネイティブAPIはそのハンドルを使用します。ネイティブAPIの実行中にコレクションと圧縮を取得すると、管理対象オブジェクトが移動し、ポインターが無効になる場合があります。
- バッファを使用してP / Invokeを実行します。バッファが小さすぎるか、渡したサイズよりも小さい場合、APIは読み取りまたは書き込みをオーバーランします
- P / Invoke呼び出しに渡すポインター(IntPtrなど)は無効(-1または0)であり、ネイティブは使用前にチェックしていません
- P / Invokeでネイティブコールを実行すると、ネイティブコードのメモリが不足し(通常は仮想)、割り当ての失敗や無効なアドレスへの読み取り/書き込みをチェックしていません
- 初期化されていないGCHandleを使用しているか、何らかの形で既にファイナライズされて収集されたオブジェクトを指している(したがって、オブジェクトを指しているのではなく、オブジェクトが使用されていたアドレスを指している)
- アプリは、スリープ/スリープ解除によって無効になったものへのハンドルを使用します。これは難解ですが、確かに起こります。たとえば、ストレージカードからアプリケーションを実行している場合、アプリ全体はRAMに読み込まれません。使用中のピースは、実行のためにデマンドページインされます。これはすべて順調です。デバイスの電源を切ると、ドライバーはすべてシャットダウンします。電源を入れると、多くのデバイスは単にストレージデバイスを再マウントします。アプリがより多くのプログラムでデマンドページングを行う必要がある場合、アプリは以前の場所ではなく、終了します。マウントされたストア上のデータベースでも同様の動作が発生する可能性があります。データベースへのオープンハンドルがある場合、スリープ/スリープ解除サイクルの後、接続ハンドルは無効になる可能性があります。
ここでは、これらのほとんどすべてがP / Invokesであり、偶然ではないという傾向に注目してください。マネージコードを単独でこれを実行するのは非常に困難です。