I am able to use feenableexcept() to change the FPE environment. However, two lines of code later, something changes my control_word. Has anybody seen this before and know how to stop it?
fedisableexcept(FE_ALL_EXCEPT);
feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_INVALID); // FE_UNDERFLOW & FE_INEXACT are too common
fegetenv(&tmp_env); // tmp_env.__control_word = 882. As expected
int AA = 1;
fegetenv(&tmp_env); // tmp_env.__control_word = 895. No good
Can the problem be that multiple threads run the program? Is there a way to set the default control_word bits so that they do not get overriden?
I have a simple C++ program that 1) loops over FPE equations, 2) catches the SIGFPE and prints some useful information, 3) clears the FPU status word using uc_mcontext.fpregs->mxcsr, 4) computes the offending operator length and then skips that operator. This way the program can continue without exiting.
For this last run I specified feenableexcept(FE_DIVBYZERO); It seems to work at the beginning but then something changes the flags and it starts capturing other FPEs. Below is the program output:
- 0: control_word = 891
The SignalCatcher program is running!
=============================================================
Test 01: (float) 1.0e-300 = 0
=============================================================
Test 02: (float) 1.0e300 = inf
=============================================================
Test 03: acos(1.01f) = nan
=============================================================
0: control_word = 895
1. insn_get_length() = 2
B: Boost stacktrace specific: main in /home/lcordova/bin/signalCatcher/main.cpp L89
F. psiginfo specific: Caught signal 8 with signal code Int_Div-by-zero(1). Exception at address 0x401658 .
Test 04: 1/0 = 1
=============================================================
0: control_word = 895
1. insn_get_length() = 5
B: Boost stacktrace specific: main in /home/lcordova/bin/signalCatcher/main.cpp L92
F. psiginfo specific: Caught signal 8 with signal code FP_Div-by-zero(3). Exception at address 0x4016ad .
Test 05: 1.0f/0.0f = 1
=============================================================
0: control_word = 895
1. insn_get_length() = 4
B: Boost stacktrace specific: in L0
F. psiginfo specific: Caught signal 8 with signal code FP_Invalid(7). Exception at address 0x2b44f640 .
Test 06: sqrt(-1) = 0
=============================================================
0: control_word = 895
1. insn_get_length() = 4
B: Boost stacktrace specific: main in /home/lcordova/bin/signalCatcher/main.cpp L77
F. psiginfo specific: Caught signal 8 with signal code FP_Underflow(5). Exception at address 0x4014f1 .
Test 01: (float) 1.0e-300 = -124.475
=============================================================
0: control_word = 895
1. insn_get_length() = 4
B: Boost stacktrace specific: main in /home/lcordova/bin/signalCatcher/main.cpp L81
F. psiginfo specific: Caught signal 8 with signal code FP_Overflow(4). Exception at address 0x40155d .
Test 02: (float) 1.0e300 = -3.86568e-34
=============================================================
0: control_word = 895
1. insn_get_length() = 4
B: Boost stacktrace specific: acos in L0
F. psiginfo specific: Caught signal 8 with signal code FP_Invalid(7). Exception at address 0x2b46d9fa .
Test 03: acos(1.01f) = nan