sigFpe.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2015 OpenFOAM Foundation
9  Copyright (C) 2011 Symscape
10  Copyright (C) 2016-2021 OpenCFD Ltd.
11 -------------------------------------------------------------------------------
12 License
13  This file is part of OpenFOAM.
14 
15  OpenFOAM is free software: you can redistribute it and/or modify it
16  under the terms of the GNU General Public License as published by
17  the Free Software Foundation, either version 3 of the License, or
18  (at your option) any later version.
19 
20  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27 
28 \*---------------------------------------------------------------------------*/
29 
30 #include "sigFpe.H"
31 #include "error.H"
32 #include "JobInfo.H"
33 #include "OSspecific.H"
34 #include "IOstreams.H"
35 #include "Switch.H"
36 #include "UList.H"
37 
38 #include <float.h> // For *fp functions
39 #include <limits>
40 
41 // File-local functions
42 #include "signalMacros.C"
43 
44 
45 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
46 
47 bool Foam::sigFpe::switchFpe_(Foam::debug::optimisationSwitch("trapFpe", 0));
48 bool Foam::sigFpe::switchNan_(Foam::debug::optimisationSwitch("setNaN", 0));
49 
50 bool Foam::sigFpe::sigActive_ = false;
51 bool Foam::sigFpe::nanActive_ = false;
52 
53 // Saved old FPE signal trapping setting (file-local variable)
54 static unsigned int oldFpe_ = 0u;
55 
56 
57 static void clearFpe()
58 {
59  #ifndef Foam_no_sigFpe
60  _clearfp();
61  _controlfp(oldFpe_, 0xFFFFFFFF);
62  #endif
63 }
64 
65 
66 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
67 
68 // Can turn on/off via env variable containing a bool (true|false|on|off ...)
69 // or by the specified flag
70 static bool isTrue(const char* envName, bool deflt)
71 {
73 
74  if (sw.good())
75  {
76  return static_cast<bool>(sw);
77  }
78 
79  // Env was not set or did not contain a valid bool value
80  return deflt;
81 }
82 
83 
84 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
85 
86 void Foam::sigFpe::sigHandler(int)
87 {
88  resetHandler("SIGFPE", SIGFPE);
89 
90  JobInfo::shutdown(); // From running -> finished
92  clearFpe();
93  ::raise(SIGFPE); // Throw signal (to old handler)
94 }
95 
96 
97 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
98 
100 {
101  set(false);
102 }
103 
104 
106 :
107  wasActive_(sigFpe::active())
108 {
109  if (wasActive_)
110  {
111  sigFpe::unset();
112  }
113 }
114 
115 
116 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
117 
119 {
120  unset(false);
121 }
122 
123 
125 {
126  restore();
127 }
128 
129 
130 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
131 
133 {
134  if (wasActive_)
135  {
136  sigFpe::set();
137  }
138  wasActive_ = false;
139 }
140 
141 
143 {
144  return isTrue("FOAM_SIGFPE", switchFpe_);
145 }
146 
147 
148 void Foam::sigFpe::set(bool verbose)
149 {
150  if (!sigActive_ && requested())
151  {
152  #ifdef Foam_no_sigFpe
153 
154  if (verbose)
155  {
156  Info<< "trapFpe: Floating point exception trapping ";
157  Info<< "- disabled on this platform" << endl;
158  }
159 
160  #else
161 
162  oldFpe_ = _controlfp(0, 0);
163 
164  const unsigned int newFpe =
165  (
166  oldFpe_ & ~(_EM_ZERODIVIDE | _EM_INVALID | _EM_OVERFLOW)
167  );
168 
169  _controlfp(newFpe, _MCW_EM);
170 
171  setHandler("SIGFPE", SIGFPE, sigHandler);
172 
173  sigActive_ = true;
174 
175  if (verbose)
176  {
177  Info<< "trapFpe: Floating point exception trapping ";
178 
179  if (sigActive_)
180  {
181  Info<< "enabled (FOAM_SIGFPE)." << endl;
182  }
183  else
184  {
185  Info<< "- not supported on this platform" << endl;
186  }
187  }
188  #endif
189  }
190 
191 
192  nanActive_ = false;
193  if (isTrue("FOAM_SETNAN", switchNan_))
194  {
195  if (verbose)
196  {
197  Info<< "setNaN : Initialise allocated memory to NaN "
198  << "- not supported on this platform" << endl;
199  }
200  }
201 }
202 
203 
204 void Foam::sigFpe::unset(bool verbose)
205 {
206  if (sigActive_)
207  {
208  if (verbose)
209  {
210  Info<< "sigFpe : Disabling floating point exception trapping"
211  << endl;
212  }
213 
214  sigActive_ = false;
215 
216  clearFpe();
217 
218  resetHandler("SIGFPE", SIGFPE);
219  }
220 
221  nanActive_ = false;
222 }
223 
224 
226 {
227  list = std::numeric_limits<scalar>::signaling_NaN();
228 }
229 
230 
231 // ************************************************************************* //
Foam::sigFpe::set
static void set(bool verbose=false)
Activate SIGFPE signal handler when FOAM_SIGFPE is set.
Definition: sigFpe.C:148
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:77
Foam::error::printStack
static void printStack(Ostream &os)
Helper function to print a stack.
Definition: dummyPrintStack.C:36
Foam::BitOps::set
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
Definition: BitOps.C:37
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Foam::resetHandler
static void resetHandler(const char *what, int sigNum)
Definition: signalMacros.C:46
Foam::sigFpe::ignore::ignore
ignore()
Constructor deactivates any previously active SIGFPE handler.
Definition: sigFpe.C:105
Foam::sigFpe::unset
static void unset(bool verbose=false)
Deactivate SIGFPE signal handler and NaN memory initialisation.
Definition: sigFpe.C:204
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
clearFpe
static void clearFpe()
Definition: sigFpe.C:57
Foam::Switch::good
bool good() const noexcept
True if the Switch represents a valid enumeration.
Definition: Switch.C:300
sigFpe.H
Foam::Switch::find
static Switch find(const std::string &str)
Definition: Switch.C:151
Foam::getEnv
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
error.H
Foam::sigFpe::fillNan
static void fillNan(UList< scalar > &list)
Fill data block with NaN values.
Definition: sigFpe.C:225
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Switch.H
Foam::sigFpe::ignore::~ignore
~ignore()
Destructor restores the original state of SIGFPE handler.
Definition: sigFpe.C:124
signalMacros.C
File-local code for setting/resetting signal handlers.
Foam::debug::optimisationSwitch
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:237
Foam::JobInfo::shutdown
static void shutdown()
Simple shutdown (finalize) of JobInfo.
Definition: JobInfo.C:98
Foam::sigFpe
Set up trapping for floating point exceptions (signal FPE).
Definition: sigFpe.H:73
Foam::sigFpe::requested
static bool requested()
Check if SIGFPE signals handler is to be enabled.
Definition: sigFpe.C:142
Foam::Perr
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
Foam::setHandler
static void setHandler(const char *what, int sigNum, void(*handler)(int))
Definition: signalMacros.C:61
UList.H
Foam::sigFpe::ignore::restore
void restore()
Restore the original state of SIGFPE handler.
Definition: sigFpe.C:132
oldFpe_
static unsigned int oldFpe_
Definition: sigFpe.C:54
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
JobInfo.H
Foam::sigFpe::sigFpe
sigFpe()
Definition: sigFpe.C:99
isTrue
static bool isTrue(const char *envName, bool deflt)
Definition: sigFpe.C:70
Foam::sigFpe::~sigFpe
~sigFpe()
Definition: sigFpe.C:118