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

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

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

最佳答案
feenableexcept函数是一个linux函数,它不是标准C或POSIX的一部分.没有可移植的方式来启用SIGFPE.

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

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

对于ARM,fenv_t包含名为__fpscr的字段.这是floating point status and control register.允许切换的位在fenv.h中枚举为__fpscr_trap_invalid,__ fpscr_trap_divbyzero等.大概你要打开__fpscr_trap_divbyzero位.

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

您可以在__control中切换的位由fenv.h中定义的FE_INEXACT,FE_UNDERFLOW等常量定义.我认为您必须关闭这些位才能为这些异常启用SIGFPE. Check the processor manual, §8.1.5.

您可以在__mxcsr中切换的位由xmmintrin.h中的_MM_MASK_INVALID,__ MM_MASK_DENORM等常量定义.我认为您需要关闭这些位以启用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
    }

您可能还需要为所有处理器执行#pragma STDC FENV_ACCESS ON.

我再次测试过这个问题.祝好运.

转载注明原文:如何在IOS应用程序中启用除以零的SIGFPE信号? - 代码日志