4

iOS 5/6 用の Xcode 4.5 (llvm 4.1 コンパイラ) でアプリを開発し、シグナルと例外ハンドラーを使用してエラーをログに記録します。ただし、ゼロ除算では SIGFPE シグナルが発生しないことがわかりました。Linux システムでは、feenableexcept を使用してトラップを設定できます。しかし、これはiosでは定義されていません。

適切なビットを fenv_t.__fpscr に設定しても、少なくとも iPhone 4 と 3gs では機能しません。

4

2 に答える 2

5

このfeenableexcept関数は、標準のCまたはPOSIXの一部ではないLinux関数です。を有効にするポータブルな方法はありませんSIGFPE

SIGFPE実際、シミュレーターはx86を実行し、デバイスはARMを実行するため、iOSシミュレーターとiOSデバイスで有効にするには異なるコードが必要です。

関数を使用して、のSIGFPEビットをオンまたはオフにしてから関数に渡すことで、有効にできると思います(ただしテストはしていません)。の定義はプロセッサ固有です。を見てください。fenv_tfegetenvfenv_tfesetenvfenv_tfenv.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_DENORMxmmintrin.hSIGFPE

    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また、すべてのプロセッサに対して行う必要がある場合もあります。

繰り返しますが、私はこれをテストしていません。幸運を。

于 2012-10-06T19:15:28.703 に答える
0

この問題を解決するためのオプションは次のとおりです。

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
于 2013-03-08T20:21:22.680 に答える