Skip to content

Enabling SIGFPE on macOS arm64

Summary

Enabling SIGFPE on macOS arm64

Example case

Compile and run applications/test/sigFpe on ARM Mac it will print Inf instead of trapping SIGFPE.

What is the current bug behaviour?

Results from applications/test/sigFpe

trapFpe: Floating point exception trapping - not supported on this platform

Provoking sigFpe (division by zero)

Infinity inf

Currently the code implemented by Tatsuya Shimizu 85760cbc is not working, because:

  1. On ARM64, __fpcr is the control register and __fpsr is the status register, see https://help.totalview.io/current/PDFs/TotalView_Reference_Guide.pdf page 453-454
  2. On ARM64, the shift is 8 bits instead of 7 bits.
  3. On ARM64, the mask definition is opposite to x86.
  4. Even if everything is correct, Apple M1 throws SIGILL instead of SIGFPE. It terminates the executable and prints illegal hardware instruction. I have fixed problem 1,2,3 in feexceptErsatz.H. For Problem 4, I did some dirty hack in sigFpe.C to enforce SIGILL in the handler. Currently there's no better way to implement this due to hardware/operating system limitations.

What is the expected correct behavior?

After setting FPE masks, the CPU can trigger floating point exceptions, but throw 'SIGILL'. My fix picks up SIGILL and handles it as SIGFPE (only for macOS ARM64).

Relevant logs and/or images

Results from applications/test/sigFpe

trapFpe: Floating point exception trapping enabled (FOAM_SIGFPE).

Provoking sigFpe (division by zero)

Infinity [stack trace]
=============
#1  Foam::sigFpe::sigHandler(int) in /Volumes/OpenFOAM/OpenFOAM-v2306/platforms/darwin64ClangDPInt32Opt/lib/libOpenFOAM.dylib
#2  _sigtramp in /usr/lib/system/libsystem_platform.dylib
#3  main in Test-sigFpe
#4  start in /usr/lib/dyld
=============
zsh: floating point exception  ./Test-sigFpe

Results from cavity tutorial case (set viscosity to negative number gives you immediate SIGFPE)

Starting time loop

Time = 0.005

Courant Number mean: 0 max: 0
smoothSolver:  Solving for Ux, Initial residual = 1, Final residual = 3.87689e+220, No Iterations 1000
smoothSolver:  Solving for Uy, Initial residual = 0, Final residual = 0, No Iterations 0
[stack trace]
=============
#1  Foam::sigFpe::sigHandler(int) in /Volumes/OpenFOAM/OpenFOAM-v2306/platforms/darwin64ClangDPInt32Opt/lib/libOpenFOAM.dylib
#2  _sigtramp in /usr/lib/system/libsystem_platform.dylib
#3  Foam::PCG::scalarSolve(Foam::Field<double>&, Foam::Field<double> const&, unsigned char) const in /Volumes/OpenFOAM/OpenFOAM-v2306/platforms/darwin64ClangDPInt32Opt/lib/libOpenFOAM.dylib
#4  Foam::PCG::solve(Foam::Field<double>&, Foam::Field<double> const&, unsigned char) const in /Volumes/OpenFOAM/OpenFOAM-v2306/platforms/darwin64ClangDPInt32Opt/lib/libOpenFOAM.dylib
#5  Foam::fvMatrix<double>::solveSegregated(Foam::dictionary const&) in /Volumes/OpenFOAM/OpenFOAM-v2306/platforms/darwin64ClangDPInt32Opt/lib/libfiniteVolume.dylib
#6  Foam::fvMatrix<double>::solveSegregatedOrCoupled(Foam::dictionary const&) in /Volumes/OpenFOAM/OpenFOAM-v2306/platforms/darwin64ClangDPInt32Opt/lib/libfiniteVolume.dylib
#7  main in /Volumes/OpenFOAM/OpenFOAM-v2306/platforms/darwin64ClangDPInt32Opt/bin/icoFoam
#8  start in /usr/lib/dyld
=============
zsh: floating point exception  icoFoam

Environment information

  • OpenFOAM version : All
  • Operating system : macOS arm64
  • Hardware info : Apple M1
  • Compiler : Clang

Possible fixes

I'm attaching two modified files in src/OSspecific/POSIX/signals. It shouldn't change anything on other platforms including x86 Macs. OpenFOAM SIGFPE can be successfully triggered on macOS arm64.

feexceptErsatz.H

sigFpe.C See comment for second version

Edited by Guanyang Xue