如何在 IOS 应用程序中除以零时启用 SIGFPE 信号?

Ter*_*ium 4 xcode exception-handling divide-by-zero ios

我在 Xcode 4.5(llvm 4.1 编译器)中为 ios 5/6 开发了一个应用程序,并使用信号和异常处理程序来记录错误。但是我发现除以零永远不会引发 SIGFPE 信号。在linux系统上,我可以使用feenableexcept来设置陷阱。但这在ios中没有定义。

将适当的位设置为 fenv_t.__fpscr 不起作用,至少对于 iphone 4 和 3gs。

rob*_*off 5

feenableexcept函数是一个不属于标准 C 或 POSIX 的 linux 函数。没有可移植的方式来启用SIGFPE.

实际上,您需要SIGFPE在 iOS 模拟器和 iOS 设备上启用不同的代码,因为模拟器运行 x86,设备运行 ARM。

我认为(但尚未测试)您可以SIGFPE通过获取fenv_tusingfegetenv函数,打开或关闭 中的某些位fenv_t,然后将其传递给fesetenv函数来启用。的定义fenv_t是特定于处理器的。看看fenv.h

对于 ARM,fenv_t包含一个名为__fpscr. 这是浮点状态和控制寄存器。你被允许切换位被列举fenv.h__fpscr_trap_invalid__fpscr_trap_divbyzero等大概要打开__fpscr_trap_divbyzero位。

对于 x86,fenv_t包含两个感兴趣的字段:__control(x87 控制字)和__mxcsr(SSE 控制/状态寄存器)。

您可以切换中的位__control由定义FE_INEXACTFE_UNDERFLOW等常量定义fenv.h。我认为你必须把位关闭,以使SIGFPE这些例外。 检查处理器手册,第 8.1.5 节

您可以切换中的位__mxcsr由定义_MM_MASK_INVALID__MM_MASK_DENORM在等常量xmmintrin.h。我认为你需要把位关闭启用SIGFPE。检查处理器手册,第 10.2.3 节。

    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
    }
Run Code Online (Sandbox Code Playgroud)

您可能还需要#pragma STDC FENV_ACCESS ON为所有处理器执行此操作。

同样,我还没有测试过任何这些。祝你好运。