Visual C++ 2005 ランタイムの初期化中に API フックなどの特殊な処理が実行される場合、C ランタイム起動中にスタックがオーバーフローしアプリケーションが異常終了する場合がある

現象
Visual C++ 2005 ランタイムの初期化中に、API フック処理などの特殊な処理を行うモジュールが初期化ルーチンへの割り込み処理を実行すると、C ランタイムの初期化状態に依存し、まれにスタックがオーバーフローする可能性があります。本現象は、アプリケーションの起動中など、C ランタイムの初期化処理中に発生するため、メイン スレッドの起動直後にスタック オーバーフローによる異常終了が発生します。現象は、ランタイムの初期化処理とフック処理のタイミングに依存して発生し、それらのタイミングはアプリケーションの実装にて制御可能な対象ではないため、明確な発生条件は存在しません。なお、同バージョン以外の製品では本問題は発生しません。
原因
API フック処理などにより C ランタイム既定の初期化ルーチンへの割り込み処理が実行された際に、C ランタイムは基本的にこのような割り込みを想定していないため、C ランタイムの初期化状態が不完全な状態でランタイムが実行され、エラーが発生する場合があります。この場合、C ランタイム内部では、エラー発生後にさらに該当エラーハンドリングの処理などに失敗し、その失敗時のエラー ハンドリング処理でも再度 C ランタイムの初期化状態に依存して再帰的にエラー処理の呼び出しが発生します。結果として、いくつかの処理が繰り返し行われ、スタックがオーバーフローしアプリケーションが異常終了します。
詳細
デバッガ等でアプリケーション終了時の処理内容が確認可能な場合、現象発生時のコールスタック (関数の呼び出し履歴) には、以下のような同一パターンの呼び出し履歴が繰り返し記録されます。

msvcr80!_get_winmajor+0x10
msvcr80!_use_encode_pointer+0x1b
msvcr80!_decode_pointer+0x4a
msvcr80!_decode_pointer+0x3f
msvcr80!__set_flsgetvalue+0x1e
msvcr80!_getptd_noexit+0x15
msvcr80!_errno+0x5

なお、API フック処理は、割り込む対象のアプリケーションやモジュールの実装に関わらず、強制的に該当の処理に置き換えて動作する仕組みとなります。このような特殊な仕組みを実装されていない場合には、本件の事象は発生しません。ただし、仮想環境やセキュリティ監視のソフトウェア等を導入されている場合には、それらの機能を利用して処理が行われている場合があります。
回避策
本問題を回避するには、Visual C++ 2005  ランタイムの初期化処理中に、API フックなどの割り込み処理を実施しないようにします。また、仮想環境やセキュリティ監視のソフトウェア等により API フックの処理が行われている可能性がある場合には、それらのソフトウェアを一時的に削除して現象が回避するかを確認します。仮想環境やセキュリティ監視のソフトウェア等により意図せず API フックが行われている場合、C ランタイム上で動作するアプリケーション側で本現象を回避する方法はありません。この場合は、Visual C++ 2008 や Visual C++ 2010 など、Visual C++ 2005 よりも新しい製品バージョンでアプリケーションをご利用ください。
状況
マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の不具合として認識しています。
注意 : これは、マイクロソフトのサポート組織内で直接作成された "緊急公開" の資料です。 この資料には、確認中の問題に関する現状ベースの情報が記載されています。 情報提供のスピードを優先するため、資料には誤植が含まれる可能性があり、予告なしに随時改定される場合があります。 その他の考慮事項については、使用条件を参照してください。
プロパティ

文書番号:2671692 - 最終更新日: 09/29/2016 14:28:00 - リビジョン: 3.0

  • kbharmony KB2671692
フィードバック