2

多くの数学的計算を実行する C++ の Visual Studio 2012/13 に組み込まれた MFC 製品があります。コプロセッサを介して浮動小数点割り込みを使用して、try/catch ブロックを設定することで計算を高速化します。これらの割り込みは Windows 7 ではうまく機能しますが、Windows 10 の更新プログラムの 1 つがシーケンスを壊しました。「シグナル」呼び出しは「ハンドラー」コールバックの正しいポインターをセットアップしますが、Windows 10 はそれを無視します。(同じコードがコンソール プログラムで機能します。MFC コードでのみ失敗します。最も単純なコードを取り除いた例でも)。SEH を使用した回避策がありますが、この問題が発生した理由を知りたいと考えています。情報をありがとう。

関連するコードは、ハンドラーが FloatException をスローする場所です (Windows 10 では割り込みがハンドラーに到達しないことに注意してください)。

   _clearfp();
   _controlfp_s(0,  _EM_INEXACT, _MCW_EM);
   signal(SIGFPE, (fptr)HandleMathError);
   try
   {
     ...calculate
   }
   catch (FloatException &e)
   {
      ...recover
      _fpreset();
      _clearfp();
      _controlfp_s(0, old_control_word, _MCW_EM);
      signal(SIGFPE, SIG_DFL);
      return;
   }

完全を期すために、MFC の失敗を確認するには、必要なコードに少なくとも 9 個のファイルが必要です。まず、単一ドキュメント、ドキュメント/ビュー、mfc 標準インターフェイス、スタティック ライブラリ、複合ドキュメントなし、データベースなし、クラシック メニューを使用して、単純な MFC アプリケーションを生成します。次に、MainFrm::OnCreate で、上記の割り込みコードを「raise(SIGFPE)」のみの計算として挿入します。「HandleMathError」と「Float Exception」の定義を次のように追加します。

typedef void( *fptr )( int );

void __cdecl HandleMathError( int sig, int subcode );

class FloatException : public std::exception
{
public:
    FloatException( int _foo )
    {
        foo = _foo;
    }
    int foo;
};

void __cdecl HandleMathError( int sig, int subcode )
{
    throw FloatException( subcode );
    return;
}

このコードでは、Windows 7 では割り込みハンドラーが入力され、Windows 10 では入力されません。シグナルを使用して存在するハンドラーのテストは、両方の OS で肯定的です。Windows 10 はハンドラーを無視しています。

4

0 に答える 0