iOS 5/6 用の Xcode 4.5 (llvm 4.1 コンパイラ) でアプリを開発し、シグナルと例外ハンドラーを使用してエラーをログに記録します。ただし、ゼロ除算では SIGFPE シグナルが発生しないことがわかりました。Linux システムでは、feenableexcept を使用してトラップを設定できます。しかし、これはiosでは定義されていません。
適切なビットを fenv_t.__fpscr に設定しても、少なくとも iPhone 4 と 3gs では機能しません。
iOS 5/6 用の Xcode 4.5 (llvm 4.1 コンパイラ) でアプリを開発し、シグナルと例外ハンドラーを使用してエラーをログに記録します。ただし、ゼロ除算では SIGFPE シグナルが発生しないことがわかりました。Linux システムでは、feenableexcept を使用してトラップを設定できます。しかし、これはiosでは定義されていません。
適切なビットを fenv_t.__fpscr に設定しても、少なくとも iPhone 4 と 3gs では機能しません。
このfeenableexcept
関数は、標準のCまたはPOSIXの一部ではないLinux関数です。を有効にするポータブルな方法はありませんSIGFPE
。
SIGFPE
実際、シミュレーターはx86を実行し、デバイスはARMを実行するため、iOSシミュレーターとiOSデバイスで有効にするには異なるコードが必要です。
関数を使用して、のSIGFPE
ビットをオンまたはオフにしてから関数に渡すことで、有効にできると思います(ただしテストはしていません)。の定義はプロセッサ固有です。を見てください。fenv_t
fegetenv
fenv_t
fesetenv
fenv_t
fenv.h
ARMの場合、 。fenv_t
という名前のフィールドが含まれます__fpscr
。これは、浮動小数点ステータスおよび制御レジスタです。切り替えることができるビットは、、などとして列挙されますfenv.h
。おそらく、ビットをオンにします。__fpscr_trap_invalid
__fpscr_trap_divbyzero
__fpscr_trap_divbyzero
x86の場合、(x87制御ワード)と(SSE制御/ステータスレジスタ)fenv_t
の2つの対象フィールドが含まれます。__control
__mxcsr
切り替えることができるビットは、__control
で定義されたFE_INEXACT
、、FE_UNDERFLOW
などの定数によって定義されfenv.h
ます。これらの例外 を有効にするには、ビットをオフにする必要があると思います。プロセッサのマニュアル、§8.1.5を確認してください。SIGFPE
切り替えることができるビットは、の定数などで__mxcsr
定義されます。を有効にするには、ビットをオフにする必要があると思います。プロセッサのマニュアル、§10.2.3を確認してください。_MM_MASK_INVALID
__MM_MASK_DENORM
xmmintrin.h
SIGFPE
fenv_t fe;
if (fegetenv(&fe) != 0) {
// error
}
#if defined __arm__
fe.__fpscr |= __fpscr_trap_divbyzero;
#elif defined __i386__
fe.__control &= ~FE_DIVBYZERO;
fe.__mxcsr &= ~_MM_MASK_DIV_ZERO;
#else
#error unknown processor architecture
#endif
if (fesetenv(&fe) != 0) {
// error
}
#pragma STDC FENV_ACCESS ON
また、すべてのプロセッサに対して行う必要がある場合もあります。
繰り返しますが、私はこれをテストしていません。幸運を。
この問題を解決するためのオプションは次のとおりです。
Rob が言ったことを実行するには、1 つの関数を使用して浮動小数点除算ゼロ トラップを有効にし、定期的にフラグをチェックします。
#include "fenv.h"
#include <iostream>
#include <csignal>
void CheckForDivideByZeroException()
{
int set_excepts;
set_excepts = fetestexcept(FE_DIVBYZERO);
if (set_excepts & FE_DIVBYZERO) {
cerr<<"Divide by zero!!!"<<endl;
feclearexcept(FE_DIVBYZERO);
}
}
void EnableDivideByZeroExceptions()
{
fenv_t fe;
if (fegetenv(&fe) != 0) {
cerr<<"ERROR - Unable to get floating point status and control register"<<endl;
raise(SIGINT);
}
#if defined __arm__
fe.__fpscr |= __fpscr_trap_divbyzero;
#elif defined __i386__
fe.__control &= ~FE_DIVBYZERO;
fe.__mxcsr &= ~_MM_MASK_DIV_ZERO;
#else
#error unknown processor architecture
#endif
if (fesetenv(&fe) != 0) {
cout<<"ERROR - Unable to trap div by zero errors"<<endl;
raise(SIGINT);
}
}
#endif
または、他のオプションは、次を OTHER_CFLAGS ビルド設定に追加することにより、すべての未定義の動作で例外を発生させるフラグを xcode で有効にすることです。
-fcatch-undefined-behavior