きれいにコンパイルするコードをいくつか追加し、このWindowsエラーを受け取りました。
---------------------------
(MonTel Administrator) 2.12.7: MtAdmin.exe - Application Error
---------------------------
The exception Privileged instruction.
(0xc0000096) occurred in the application at location 0x00486752.
私はバグハントに取り掛かろうとしており、それがたまたまこのメッセージを生成するだけの、私が行った愚かなことであると期待しています。コードは問題なくコンパイルされ、エラーや警告は発生しません。 EXEファイルのサイズは1,454,132バイトまで大きくなり、ODCS.lib
へのリンクが含まれていますが、それ以外の場合は、Win32 APIへの純粋なCであり、DEBUGがオンになっています(Windows 2000のP4で実行)。
質問に答えるために、特権命令は、「スーパーバイザー」(またはリング0)モードでのみ実行できるプロセッサーのオペコード(アセンブラー命令)です。これらのタイプの命令は、WindowsカーネルからI/Oデバイスや保護されたデータ構造にアクセスするために使用される傾向があります。
通常のプログラムは「ユーザーモード」(Ring-3)で実行され、I/Oデバイスなどへの直接アクセスを禁止します。
他の人が述べたように、原因はおそらく破損したスタックまたはめちゃくちゃな関数ポインター呼び出しです。
この種のことは通常、無効なデータを指す関数ポインターを使用するときに発生します。リターンスタックを破棄するコードがある場合にも発生する可能性があります。これらの種類のバグは、通常、再現が難しいため、追跡するのが非常に難しい場合があります。
特権命令は、リング0(つまりカーネルモード)でのみ実行が許可されているIA-32命令です。ユーザー空間でこれを実行している場合は、非常に古いEXEまたは破損したバイナリのいずれかを取得しています。
私が疑ったように、それは私がしたことは愚かなことでした。上記のメッセージのコメントにいくつかの手掛かりがあるため、これは2倍の速さで解決したと思います。特に、アプリの初期段階でスタックを上書きすることを指摘してくれた方に感謝します。私は実際にいくつかの回答がより有用であるとわかりました。質問の答えとしてマークした投稿は、どこを探すべきかについて手がかりとキューに入れられたので、その回答を要約するのが最善だと思います。
結局のところ、いくつかのツールバーボタン情報(スタック上にある)を保持する配列の最大サイズを超えるボタンを追加したところです。私はそれを忘れていました
#define MAX_NUM_TOOBAR_BUTTONS(24)
も存在した!
私が考えることができる最初の確率は、ローカル配列を使用している可能性があり、それが関数宣言の先頭近くにあることです。境界チェックが異常になり、戻りアドレスを上書きします。これは、カーネルのみが実行を許可されている命令を指します。
私は2000年にVisual c ++ 6.0でこれを見ました。
デバッグC++ライブラリには、例外ハンドラー内の物理I/O命令への呼び出しがありました。私が正しく覚えていれば、DMAベースレジスタに使用されていたI/Oポートにステータスをダンプしていました。Microsoftの誰かがデバッガカードに使用していたと思います。
診断コードが実行される原因となる可能性のあるエラー状態を探します。
私はデバッグしてバックトラックし、逆アセンブリを読んでいました。 std::string
の処理中に例外が発生しました。おそらく最後からインデックスを作成しています。
カーネルモードで実行すると、オペレーティングシステムはカーネルとユーザープログラムのメモリの両方に無制限にアクセスできます。
ベースレジスタと制限レジスタのロード命令は特権命令です。
エラーの場所0x00486752は、実行可能コードが通常置かれる前に、私には本当に小さいようです。私はダニエルに同意します、それは私への野生のポインターのように見えます。
過去15年間に製造されたほとんどのプロセッサのCPUには、非常に強力な特別な命令がいくつかあります。これらの特権付き命令は、オペレーティングシステムのカーネルアプリケーション用に保持されており、ユーザーが作成したプログラムでは使用できません。
これにより、ユーザー作成プログラムがシステムに与える可能性のある損傷が制限され、システムが実際にクラッシュする回数が削減されます。