diff --git a/src/OSspecific/POSIX/signals/sigFpe.C b/src/OSspecific/POSIX/signals/sigFpe.C index 5488f2e526020e939c94a3b522a5982b19adf887..237c0dfdc9887737fe397986c24b600681ec067f 100644 --- a/src/OSspecific/POSIX/signals/sigFpe.C +++ b/src/OSspecific/POSIX/signals/sigFpe.C @@ -45,6 +45,8 @@ License struct sigaction Foam::sigFpe::oldAction_; +bool Foam::sigFpe::sigFpeActive_ = false; + void Foam::sigFpe::fillNan(UList<scalar>& lst) { lst = std::numeric_limits<scalar>::signaling_NaN(); @@ -114,7 +116,7 @@ void Foam::sigFpe::sigHandler(int) Foam::sigFpe::sigFpe() { - oldAction_.sa_handler = NULL; + set(false); } @@ -122,28 +124,7 @@ Foam::sigFpe::sigFpe() Foam::sigFpe::~sigFpe() { - if (env("FOAM_SIGFPE")) - { - #ifdef LINUX_GNUC - // Reset signal - if (oldAction_.sa_handler && sigaction(SIGFPE, &oldAction_, NULL) < 0) - { - FatalErrorIn - ( - "Foam::sigFpe::~sigFpe()" - ) << "Cannot reset SIGFPE trapping" - << abort(FatalError); - } - #endif - } - - if (env("FOAM_SETNAN")) - { - #ifdef LINUX - // Disable initialization to NaN - mallocNanActive_ = false; - #endif - } + unset(false); } @@ -151,16 +132,7 @@ Foam::sigFpe::~sigFpe() void Foam::sigFpe::set(const bool verbose) { - if (oldAction_.sa_handler) - { - FatalErrorIn - ( - "Foam::sigFpe::set()" - ) << "Cannot call sigFpe::set() more than once" - << abort(FatalError); - } - - if (env("FOAM_SIGFPE")) + if (!sigFpeActive_ && env("FOAM_SIGFPE")) { bool supported = false; @@ -187,6 +159,7 @@ void Foam::sigFpe::set(const bool verbose) << abort(FatalError); } + sigFpeActive_ = true; #elif defined(sgiN32) || defined(sgiN32Gcc) supported = true; @@ -209,6 +182,9 @@ void Foam::sigFpe::set(const bool verbose) _ABORT_ON_ERROR, NULL ); + + sigFpeActive_ = true; + #endif @@ -251,4 +227,52 @@ void Foam::sigFpe::set(const bool verbose) } +void Foam::sigFpe::unset(const bool verbose) +{ + #ifdef LINUX_GNUC + // Reset signal + if (sigFpeActive_) + { + if (verbose) + { + Info<< "sigFpe : Disabling floating point exception trapping" + << endl; + } + + if (sigaction(SIGFPE, &oldAction_, NULL) < 0) + { + FatalErrorIn + ( + "Foam::sigFpe::unset(const bool)" + ) << "Cannot reset SIGFPE trapping" + << abort(FatalError); + } + + // Reset exception raising + int oldExcept = fedisableexcept + ( + FE_DIVBYZERO + | FE_INVALID + | FE_OVERFLOW + ); + + if (oldExcept == -1) + { + FatalErrorIn + ( + "sigFpe::unset(const bool)" + ) << "Cannot reset SIGFPE trapping" + << abort(FatalError); + } + sigFpeActive_ = false; + } + #endif + + #ifdef LINUX + // Disable initialization to NaN + mallocNanActive_ = false; + #endif +} + + // ************************************************************************* // diff --git a/src/OSspecific/POSIX/signals/sigFpe.H b/src/OSspecific/POSIX/signals/sigFpe.H index 603c4b5ea0050222d0cec72b9f0e87fdfe651b0b..ed5e09f9049171219d8cb7388151c1f982030521 100644 --- a/src/OSspecific/POSIX/signals/sigFpe.H +++ b/src/OSspecific/POSIX/signals/sigFpe.H @@ -35,6 +35,10 @@ Description also set, this will cause usage of uninitialized scalars to trigger an abort. + Can be used either directly through the static member functions or + through the scope of the object (constructor sets trapping; destructor + restores original). + SourceFiles sigFpe.C @@ -72,6 +76,9 @@ class sigFpe //- Saved old signal trapping setting static struct sigaction oldAction_; + //- Flag to indicate floating point trapping is enabled + static bool sigFpeActive_; + // Static data members @@ -98,7 +105,10 @@ public: //- Activate SIGFPE signal handler when FOAM_SIGFPE is %set // Fill memory with NaN when FOAM_SETNAN is %set - void set(const bool verbose); + static void set(const bool verbose); + + //- Deactivate SIGFPE signal handler and NaN memory initialisation + static void unset(const bool verbose); //- Flag to indicate mallocNan is enabled static bool mallocNanActive_; diff --git a/src/OSspecific/POSIX/signals/sigInt.C b/src/OSspecific/POSIX/signals/sigInt.C index 29c71f5ba74efa88163771918d0c94951d25a3a6..bfb34d1a408693449b18b1d1197a1862facb115c 100644 --- a/src/OSspecific/POSIX/signals/sigInt.C +++ b/src/OSspecific/POSIX/signals/sigInt.C @@ -32,6 +32,8 @@ License struct sigaction Foam::sigInt::oldAction_; +bool Foam::sigInt::sigActive_ = false; + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -59,7 +61,7 @@ void Foam::sigInt::sigHandler(int) Foam::sigInt::sigInt() { - oldAction_.sa_handler = NULL; + set(false); } @@ -67,15 +69,7 @@ Foam::sigInt::sigInt() Foam::sigInt::~sigInt() { - // Reset old handling - if (sigaction(SIGINT, &oldAction_, NULL) < 0) - { - FatalErrorIn - ( - "Foam::sigInt::~sigInt()" - ) << "Cannot reset SIGINT trapping" - << abort(FatalError); - } + unset(false); } @@ -83,26 +77,38 @@ Foam::sigInt::~sigInt() void Foam::sigInt::set(const bool) { - if (oldAction_.sa_handler) + if (!sigActive_) { - FatalErrorIn - ( - "Foam::sigInt::set()" - ) << "Cannot call sigInt::set() more than once" - << abort(FatalError); + struct sigaction newAction; + newAction.sa_handler = sigHandler; + newAction.sa_flags = SA_NODEFER; + sigemptyset(&newAction.sa_mask); + if (sigaction(SIGINT, &newAction, &oldAction_) < 0) + { + FatalErrorIn + ( + "Foam::sigInt::set()" + ) << "Cannot set SIGINT trapping" + << abort(FatalError); + } + sigActive_ = true; } +} + - struct sigaction newAction; - newAction.sa_handler = sigHandler; - newAction.sa_flags = SA_NODEFER; - sigemptyset(&newAction.sa_mask); - if (sigaction(SIGINT, &newAction, &oldAction_) < 0) +void Foam::sigInt::unset(const bool) +{ + if (sigActive_) { - FatalErrorIn - ( - "Foam::sigInt::set()" - ) << "Cannot set SIGINT trapping" - << abort(FatalError); + if (sigaction(SIGINT, &oldAction_, NULL) < 0) + { + FatalErrorIn + ( + "Foam::sigInt::unset()" + ) << "Cannot reset SIGINT trapping" + << abort(FatalError); + } + sigActive_ = false; } } diff --git a/src/OSspecific/POSIX/signals/sigInt.H b/src/OSspecific/POSIX/signals/sigInt.H index f079aa713c3d287c43c52313f04bef2b3c28f2ad..cbfdf3a009958e68729d5eb65eaeedb3cab1006d 100644 --- a/src/OSspecific/POSIX/signals/sigInt.H +++ b/src/OSspecific/POSIX/signals/sigInt.H @@ -30,6 +30,10 @@ Description The standard interupt handler is overridden to ensure that the runningJob file is removed. + Can be used either directly through the static member functions or + through the scope of the object (constructor sets trapping; destructor + restores original). + See Also Foam::JobInfo @@ -59,6 +63,9 @@ class sigInt //- Saved old signal trapping setting static struct sigaction oldAction_; + //- Flag to indicate signal trapping is enabled + static bool sigActive_; + // Private Member Functions @@ -80,7 +87,10 @@ public: // Member functions //- Activate SIGINT signal handler - void set(const bool verbose); + static void set(const bool verbose); + + //- Deactivate SIGINT signal handler + static void unset(const bool verbose); }; diff --git a/src/OSspecific/POSIX/signals/sigQuit.C b/src/OSspecific/POSIX/signals/sigQuit.C index 9c16d3d33de943380904cb6000474cd9cd8055ad..9bfe6543bccc643eece5d84e62c8b8ba6fda9d77 100644 --- a/src/OSspecific/POSIX/signals/sigQuit.C +++ b/src/OSspecific/POSIX/signals/sigQuit.C @@ -32,6 +32,8 @@ License struct sigaction Foam::sigQuit::oldAction_; +bool Foam::sigQuit::sigActive_ = false; + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -61,7 +63,7 @@ void Foam::sigQuit::sigHandler(int) Foam::sigQuit::sigQuit() { - oldAction_.sa_handler = NULL; + set(false); } @@ -69,15 +71,7 @@ Foam::sigQuit::sigQuit() Foam::sigQuit::~sigQuit() { - // Reset old handling - if (oldAction_.sa_handler && sigaction(SIGQUIT, &oldAction_, NULL) < 0) - { - FatalErrorIn - ( - "Foam::sigQuit::~sigQuit()" - ) << "Cannot reset SIGQUIT trapping" - << abort(FatalError); - } + unset(false); } @@ -85,26 +79,38 @@ Foam::sigQuit::~sigQuit() void Foam::sigQuit::set(const bool verbose) { - if (oldAction_.sa_handler) + if (!sigActive_) { - FatalErrorIn - ( - "Foam::sigQuit::set()" - ) << "Cannot call sigQuit::set() more than once" - << abort(FatalError); + struct sigaction newAction; + newAction.sa_handler = sigHandler; + newAction.sa_flags = SA_NODEFER; + sigemptyset(&newAction.sa_mask); + if (sigaction(SIGQUIT, &newAction, &oldAction_) < 0) + { + FatalErrorIn + ( + "Foam::sigQuit::set()" + ) << "Cannot set SIGQUIT trapping" + << abort(FatalError); + } + sigActive_ = true; } +} + - struct sigaction newAction; - newAction.sa_handler = sigHandler; - newAction.sa_flags = SA_NODEFER; - sigemptyset(&newAction.sa_mask); - if (sigaction(SIGQUIT, &newAction, &oldAction_) < 0) +void Foam::sigQuit::unset(const bool) +{ + if (sigActive_) { - FatalErrorIn - ( - "Foam::sigQuit::set()" - ) << "Cannot set SIGQUIT trapping" - << abort(FatalError); + if (sigaction(SIGQUIT, &oldAction_, NULL) < 0) + { + FatalErrorIn + ( + "Foam::sigQuit::unset()" + ) << "Cannot reset SIGQUIT trapping" + << abort(FatalError); + } + sigActive_ = false; } } diff --git a/src/OSspecific/POSIX/signals/sigQuit.H b/src/OSspecific/POSIX/signals/sigQuit.H index 8dc04993519c0dd710790764aecb6a512e1b6ab1..d90573c1fa03ca2dde8b3e0e6c167c25254e93a8 100644 --- a/src/OSspecific/POSIX/signals/sigQuit.H +++ b/src/OSspecific/POSIX/signals/sigQuit.H @@ -29,6 +29,9 @@ Description The standard interupt handler is overridden to ensure that the runningJob file is removed. + Can be used either directly through the static member functions or + through the scope of the object (constructor sets trapping; destructor + restores original). See Also Foam::JobInfo @@ -59,6 +62,9 @@ class sigQuit //- Saved old signal trapping setting static struct sigaction oldAction_; + //- Flag to indicate signal trapping is enabled + static bool sigActive_; + // Private Member Functions @@ -81,7 +87,10 @@ public: // Member functions //- Activate SIGQUIT signal handler - void set(const bool verbose); + static void set(const bool verbose); + + //- Deactivate SIGQUIT signal handler + static void unset(const bool verbose); }; diff --git a/src/OSspecific/POSIX/signals/sigSegv.C b/src/OSspecific/POSIX/signals/sigSegv.C index 11a30699769bd5e8e65da02c8723b297fd2d2f5b..e5e6e1b3e63115ba7ca78d9e20e219394180b74f 100644 --- a/src/OSspecific/POSIX/signals/sigSegv.C +++ b/src/OSspecific/POSIX/signals/sigSegv.C @@ -32,6 +32,8 @@ License struct sigaction Foam::sigSegv::oldAction_; +bool Foam::sigSegv::sigActive_ = false; + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -61,7 +63,7 @@ void Foam::sigSegv::sigHandler(int) Foam::sigSegv::sigSegv() { - oldAction_.sa_handler = NULL; + set(false); } @@ -69,15 +71,7 @@ Foam::sigSegv::sigSegv() Foam::sigSegv::~sigSegv() { - // Reset old handling - if (sigaction(SIGSEGV, &oldAction_, NULL) < 0) - { - FatalErrorIn - ( - "Foam::sigSegv::~sigSegv()" - ) << "Cannot reset SIGSEGV trapping" - << abort(FatalError); - } + unset(false); } @@ -85,26 +79,38 @@ Foam::sigSegv::~sigSegv() void Foam::sigSegv::set(const bool) { - if (oldAction_.sa_handler) + if (!sigActive_) { - FatalErrorIn - ( - "Foam::sigSegv::set()" - ) << "Cannot call sigSegv::set() more than once" - << abort(FatalError); + struct sigaction newAction; + newAction.sa_handler = sigHandler; + newAction.sa_flags = SA_NODEFER; + sigemptyset(&newAction.sa_mask); + if (sigaction(SIGSEGV, &newAction, &oldAction_) < 0) + { + FatalErrorIn + ( + "Foam::sigSegv::set()" + ) << "Cannot set SIGSEGV trapping" + << abort(FatalError); + } + sigActive_ = true; } +} + - struct sigaction newAction; - newAction.sa_handler = sigHandler; - newAction.sa_flags = SA_NODEFER; - sigemptyset(&newAction.sa_mask); - if (sigaction(SIGSEGV, &newAction, &oldAction_) < 0) +void Foam::sigSegv::unset(const bool) +{ + if (sigActive_) { - FatalErrorIn - ( - "Foam::sigSegv::set()" - ) << "Cannot set SIGSEGV trapping" - << abort(FatalError); + if (sigaction(SIGSEGV, &oldAction_, NULL) < 0) + { + FatalErrorIn + ( + "Foam::sigSegv::unset()" + ) << "Cannot reset SIGSEGV trapping" + << abort(FatalError); + } + sigActive_ = false; } } diff --git a/src/OSspecific/POSIX/signals/sigSegv.H b/src/OSspecific/POSIX/signals/sigSegv.H index 0cfaf05eee4e8904d2c2aaa886c72e2489e64b7b..e4cc7c8d40097c7b0efb48198971d2545d7dbb1a 100644 --- a/src/OSspecific/POSIX/signals/sigSegv.H +++ b/src/OSspecific/POSIX/signals/sigSegv.H @@ -29,6 +29,9 @@ Description The standard interupt handler is overridden to ensure that the runningJob file is removed. + Can be used either directly through the static member functions or + through the scope of the object (constructor sets trapping; destructor + restores original). See Also Foam::JobInfo @@ -59,6 +62,9 @@ class sigSegv //- Saved old signal trapping setting static struct sigaction oldAction_; + //- Flag to indicate signal trapping is enabled + static bool sigActive_; + // Private Member Functions @@ -81,7 +87,10 @@ public: // Member functions //- Activate SIGSEGV signal handler - void set(const bool verbose); + static void set(const bool verbose); + + //- Deactivate SIGSEGV signal handler + static void unset(const bool verbose); }; diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index ea72b7083e07d41be943a8877b7125e994517e7f..e40181e5d3d4b1e6f88dc74a385c76b3e403317d 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -33,6 +33,10 @@ License #include "labelList.H" #include "regIOobject.H" #include "dynamicCode.H" +#include "sigFpe.H" +#include "sigInt.H" +#include "sigQuit.H" +#include "sigSegv.H" #include <cctype> @@ -868,10 +872,10 @@ void Foam::argList::parse // Switch on signal trapping. We have to wait until after Pstream::init // since this sets up its own ones. - sigFpe_.set(bannerEnabled); - sigInt_.set(bannerEnabled); - sigQuit_.set(bannerEnabled); - sigSegv_.set(bannerEnabled); + sigFpe::set(bannerEnabled); + sigInt::set(bannerEnabled); + sigQuit::set(bannerEnabled); + sigSegv::set(bannerEnabled); if (bannerEnabled) { diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H index 12be421f80005cafcf671ef3bdc4bb118ef77c15..e242af23141b28c11d7f65260f74504034f46e5e 100644 --- a/src/OpenFOAM/global/argList/argList.H +++ b/src/OpenFOAM/global/argList/argList.H @@ -86,11 +86,6 @@ SourceFiles #include "IStringStream.H" #include "OSspecific.H" -#include "sigFpe.H" -#include "sigInt.H" -#include "sigQuit.H" -#include "sigSegv.H" - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam @@ -118,12 +113,6 @@ class argList fileName case_; string argListStr_; - // Signal handlers - sigFpe sigFpe_; - sigInt sigInt_; - sigQuit sigQuit_; - sigSegv sigSegv_; - // Private Member Functions diff --git a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.C b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.C index dea4fca5fe8dc6cfaafb8255ebdd054223b33369..78ab1c373518301f4287d04d8a564fdea9511459 100644 --- a/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.C +++ b/src/postProcessing/functionObjects/graphics/runTimePostProcessing/runTimePostProcessing.C @@ -31,6 +31,7 @@ License #include "surface.H" #include "text.H" #include "Time.H" +#include "sigFpe.H" // VTK includes #include "vtkPolyDataMapper.h" @@ -143,6 +144,10 @@ void Foam::runTimePostProcessing::write() Info<< type() << " " << name_ << " output:" << nl << " Constructing scene" << endl; + // Unset any floating point trapping (some low-level rendering functionality + // does not like it) + sigFpe::unset(false); + // Initialise render window vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); @@ -204,6 +209,9 @@ void Foam::runTimePostProcessing::write() surfaces_[i].updateActors(position); } } + + // Reset any floating point trapping + sigFpe::set(false); }