2011-03-14 10 views
26

私は例外0xc0000005について疑問を抱いていました。アクセス違反の範囲は「0xc0000005」と正確には何ですか?

I.e.私は、アプリケーションが別のプロセスに属する解放されたメモリ/メモリにアクセスしようとすると、これを起こします。
しかし、たとえば、ハードウェア用にマップされたアドレスはどうですか?または有効範囲外の住所?同じコードでこれらのフォルトへのアクセスを試みましたか、それとも自分自身が持っていますか? プロセスが所有する有効なアドレスへの読み込みに失敗しましたか?

本来、この例外が発生したときにアプリケーションが失敗した場合、何が間違っているのかを知りたいのですが、これはアプリからしか得られなかった狭い間違いです。コードやハードウェアの問題を含む何かを見ていますか?

(私はこの上のMSDNのページが存在する必要があります知っているが、検索GoogleやMSDNには、ランダムなアプリケーションのトラブルシューティングの予想される100ページが表示されます;))

ありがとう!

答えて

31

これをドリルダウンするには、プロセッサのマニュアルを読む必要があります。これは、プロセッサの例外として最もよく記述されている「トラップ」によってトリガされます。トラップはコードの実行を中断させ、オペレーティングシステムの "キャッチ"ハンドラが障害を処理できるようにします。非常に一般的な問題は、プロセッサがまだマップされていないRAMからデータを読み込もうとしたときに発生するページフォールトです。これが仮想メモリの実装方法です。

アクセス違反は、オペレーティングシステムが処理方法を知らないハードフォールトのトラップグループに属します。プロセッサーマニュアルの「一般保護違反」と呼ばれています。これはちょっとした袋ですが、GPFを引き起こす方法はたくさんあります。これまでのところ、最も一般的なのは、マップされていないメモリを読み込もうとしています。通常、ヒープメモリの破損が原因です。続いて、有効でないか、特権コードによってのみ実行できるマシンコード命令を実行しようとすると、通常はスタックメモリの破損が原因です。

これらのトラップは、プロセッサが単にプログラムを実行し続けることができないほど厄介です。オペレーティングシステムは確かにそれをどのように処理するのか分からない、それはプログラムが良い知られているコードにプロセッサを急いでするショットを与えるためにAccessViolation例外が発生します。コード内で__try/__exceptというキーワードを使用すると可能です。カスタムエラー報告以外の素晴らしいアイデアbtwでは、あなたのプログラムの状態がどのようにして死ぬ前に突然変異してしまったのか、それを元に戻すことができないのかどうかは分かりません。

このようなSEHハンドラがなければ、これはWindowsが提供するバックストップになります。 SetUnhandledExceptionFilter()で自分自身を提供できます。クラッシュレポートをカスタマイズするのに便利です。システムが提供するシステムは、Windowsエラー報告コンポーネントであるWERを起動することで終了します。最終的にプロセスが終了します。

+1

明確で正確な説明をありがとう。私はそれがプロセッサ自体から生じたものではないことを認識していました。 「彼らが来るほど厄介である」確かに!これらの例外/トラップ/割り込みがトリガされたときにプロセッサが有用な情報を戻すまでにどれくらいの時間がかかるのだろうか? – sebf

+0

ありがとう! (有用なものはいつもいいですよね?):) – sebf

0

私はgoogleで "アクセス違反"(引用符なし)の私の最初の結果としてthisを取得しました。私は詳細は分かりませんが、AVはただのことを意味します:プロセッサは、現在の状態が許さない特定のアドレスに対して読み書きしようとしました。これは、ハードウェアの問題、バスエラー、マッピングされていない仮想メモリ、不正なCPU、アクセス保護を侵害していることを示すものはほとんどありません。

+0

通常、ソフトウェアのバグが原因です。 – Zeek

13

まず、ユーザーモードプロセスのアドレスは仮想アドレスであることを理解する必要があります。それらはハードウェアへのアクセスに使用される実際のアドレスではありません。むしろ、「変換ルックアサイドバッファ」内の一致するエントリを見つけるCPU(メモリ管理ユニットの一部)に仮想から物理への変換回路が存在する。各コンテキスト切り替え中に、OSはプロセスに属するメモリマッピングをTLBに埋め込みます。

したがって、他のプロセスに属するメモリにアクセスする方法や、ハードウェアにアクセスすることはできません。このアクセスが検出されて失敗するわけではありません。プログラムに属していないメモリにはマッピングが存在しません。

プログラムがどこにもマップされていないアドレスにアクセスすると、Hans氏は言ったようにトラップを起こします。それは "ページ違反"と "アクセス違反"と同じトラップです。最初に、OSはアドレスが有効であるがTLBにないかどうかをチェックします(たとえば、PCのメモリが不足し、一部がディスクにスワップアウトされたなど)。その場合、OSはデータを物理RAMに戻し、TLBに適切なマッピングを設定し、プログラムの実行を継続します。 OSがアドレスが完全に無効であると判断した場合(スワップ位置は関連付けられていません)、「アクセス違反」(Windows命名)または「セグメンテーションフォールト」(POSIX命名)が生成されます。

通常、原因はロジックバグですが、ポインターの1つでビットが変更されたRAMの障害が発生すると、ハードウェアの障害によってアクセス違反が発生する可能性があります。

+0

TLBの動作の説明をありがとうございます。TLBの動作については、この例外がどのように発生するかを理解する上で非常に役立ちます。私はこれらの技術的な詳細すべてを非常に興味深いと思っていますが、これまで私が使ってきたユーザーモデルは、以前使っていたはるかに単純なプロセッサのものの大きなバージョンに過ぎませんでした。私はそれを正しく理解できるように、x86マニュアルを見つけようとします。 – sebf

関連する問題