これは、ここ数日間私を困惑させてきました!
ゼロ除算を実行しているアプリケーションがあります。そのアプリケーションは、浮動小数点例外のマスクを変更する _controlfp_s 関数を呼び出して、そのような場合に例外を発生させるように意図的に構築されています。
現在、ほぼすべてのマシンでゼロ除算を実行すると、Visual Studio 2005 デバッガーがソース ファイル内の適切な場所で中断します。ただし、1 台のマシンでは、破損の場所がいたるところにあり、破損の実際の原因とは無関係であるように見えます。テストとして、次のコード行だけで簡単な C win32 プログラムを作成しました。
int main(int argc, char *argv[])
{
float temp1, temp2, temp3;
unsigned int control;
_controlfp_s(&control, (_EM_UNDERFLOW + _EM_INEXACT, _MCW_EM);
temp1=1.0;
temp2=0.0;
temp3=temp1/temp2;
return 0;
}
これらすべての「良い」マシンでは、コードは temp3 で壊れます。ただし、悪いマシンでは、コードは次の場所で壊れます。
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\crt\src\tidtable.c
関数:
__set_flsgetvalue()
アセンブリ コードをステップ実行するときにレジスタを見ると、「fstp」命令を実行するまではすべて問題ないように見えます...その後、すべてのレジスタが台無しになっているように見えます (正常なマシンでは期待どおりに見えます)。良いマシンと悪いマシンのスタックを比較すると、良いマシンには見られない悪いマシンにもスタック エントリが表示されます...
この最初のパスを短くするために、ここではかなりの詳細をスキップしています...しかし、誰かが親切に助けようとする場合は、さらに追加します.
注: OS Win7 x64、最新の VS2005 Service Pack をすべて実行。同じソフトウェアとサービス パックを実行している同様の (動作している) マシンとの比較。VS2010 で実行すると、同じ奇妙な動作が発生します。
前もって感謝します。