diff --git a/src/OSspecific/POSIX/signals/sigFpe.C b/src/OSspecific/POSIX/signals/sigFpe.C index 12dcb6cff151146284399c5915f168b5654ccf84..5488f2e526020e939c94a3b522a5982b19adf887 100644 --- a/src/OSspecific/POSIX/signals/sigFpe.C +++ b/src/OSspecific/POSIX/signals/sigFpe.C @@ -30,18 +30,13 @@ License #include "IOstreams.H" #ifdef LINUX_GNUC - -# ifndef __USE_GNU -# define __USE_GNU -# endif - -# include <fenv.h> -# include <malloc.h> - + #ifndef __USE_GNU + #define __USE_GNU + #endif + #include <fenv.h> + #include <malloc.h> #elif defined(sgiN32) || defined(sgiN32Gcc) - -# include <sigfpe.h> - + #include <sigfpe.h> #endif #include <limits> @@ -50,42 +45,48 @@ License struct sigaction Foam::sigFpe::oldAction_; - -void Foam::sigFpe::fillSignallingNan(UList<scalar>& lst) +void Foam::sigFpe::fillNan(UList<scalar>& lst) { lst = std::numeric_limits<scalar>::signaling_NaN(); } +bool Foam::sigFpe::mallocNanActive_ = false; -#ifdef LINUX - -void *(*Foam::sigFpe::oldMallocHook_)(size_t, const void *) = NULL; -void* Foam::sigFpe::nanMallocHook_(size_t size, const void *caller) +#ifdef LINUX +extern "C" { - void *result; + extern void* __libc_malloc(size_t size); - // Restore all old hooks - __malloc_hook = oldMallocHook_; + // Override the GLIBC malloc to support mallocNan + void* malloc(size_t size) + { + if (Foam::sigFpe::mallocNanActive_) + { + return Foam::sigFpe::mallocNan(size); + } + else + { + return __libc_malloc(size); + } + } +} - // Call recursively - result = malloc(size); +void* Foam::sigFpe::mallocNan(size_t size) +{ + // Call the low-level GLIBC malloc function + void * result = __libc_malloc(size); - // initialize to signalling NaN + // Initialize to signalling NaN UList<scalar> lst(reinterpret_cast<scalar*>(result), size/sizeof(scalar)); - fillSignallingNan(lst); - - // Restore our own hooks - __malloc_hook = nanMallocHook_; + sigFpe::fillNan(lst); return result; } - #endif #ifdef LINUX_GNUC - void Foam::sigFpe::sigHandler(int) { // Reset old handling @@ -106,7 +107,6 @@ void Foam::sigFpe::sigHandler(int) // Throw signal (to old handler) raise(SIGFPE); } - #endif @@ -124,8 +124,7 @@ Foam::sigFpe::~sigFpe() { if (env("FOAM_SIGFPE")) { -# ifdef LINUX_GNUC - + #ifdef LINUX_GNUC // Reset signal if (oldAction_.sa_handler && sigaction(SIGFPE, &oldAction_, NULL) < 0) { @@ -135,21 +134,15 @@ Foam::sigFpe::~sigFpe() ) << "Cannot reset SIGFPE trapping" << abort(FatalError); } - -# endif + #endif } if (env("FOAM_SETNAN")) { -# ifdef LINUX_GNUC - - // Reset to standard malloc - if (oldAction_.sa_handler) - { - __malloc_hook = oldMallocHook_; - } - -# endif + #ifdef LINUX + // Disable initialization to NaN + mallocNanActive_ = false; + #endif } } @@ -171,7 +164,7 @@ void Foam::sigFpe::set(const bool verbose) { bool supported = false; -# ifdef LINUX_GNUC + #ifdef LINUX_GNUC supported = true; feenableexcept @@ -195,7 +188,7 @@ void Foam::sigFpe::set(const bool verbose) } -# elif defined(sgiN32) || defined(sgiN32Gcc) + #elif defined(sgiN32) || defined(sgiN32Gcc) supported = true; sigfpe_[_DIVZERO].abort=1; @@ -216,8 +209,7 @@ void Foam::sigFpe::set(const bool verbose) _ABORT_ON_ERROR, NULL ); - -# endif + #endif if (verbose) @@ -238,20 +230,13 @@ void Foam::sigFpe::set(const bool verbose) if (env("FOAM_SETNAN")) { - bool supported = false; - -# ifdef LINUX_GNUC - supported = true; - - // Set our malloc - __malloc_hook = Foam::sigFpe::nanMallocHook_; - -# endif - + #ifdef LINUX + mallocNanActive_ = true; + #endif if (verbose) { - if (supported) + if (mallocNanActive_) { Info<< "SetNaN : Initialising allocated memory to NaN" << " (FOAM_SETNAN)." << endl; diff --git a/src/OSspecific/POSIX/signals/sigFpe.H b/src/OSspecific/POSIX/signals/sigFpe.H index c9e9b40f9a7608988e73e56fbd160fb08020c471..603c4b5ea0050222d0cec72b9f0e87fdfe651b0b 100644 --- a/src/OSspecific/POSIX/signals/sigFpe.H +++ b/src/OSspecific/POSIX/signals/sigFpe.H @@ -45,12 +45,13 @@ SourceFiles #include <signal.h> -#if defined(linux) || defined(linuxAMD64) || defined(linuxIA64) -# define LINUX +#if defined(linux) || defined(linux64) || defined(linuxIA64) || \ + defined(linuxARM7) || defined(linuxPPC64) || defined(linuxPPC64le) + #define LINUX #endif #if defined(LINUX) && defined(__GNUC__) -# define LINUX_GNUC + #define LINUX_GNUC #endif #include "UList.H" @@ -71,14 +72,6 @@ class sigFpe //- Saved old signal trapping setting static struct sigaction oldAction_; - #ifdef LINUX - //- Saved old malloc - static void *(*oldMallocHook_)(size_t, const void *); - - //- NaN malloc function. From malloc_hook manpage. - static void* nanMallocHook_(size_t size, const void *caller); - #endif - // Static data members @@ -107,8 +100,16 @@ public: // Fill memory with NaN when FOAM_SETNAN is %set void set(const bool verbose); - //- Helper: fill block of data with NaN - static void fillSignallingNan(UList<scalar>&); + //- Flag to indicate mallocNan is enabled + static bool mallocNanActive_; + + #ifdef LINUX + //- Malloc function which initializes to NaN + static void* mallocNan(size_t size); + #endif + + //- Fill block of data with NaN + static void fillNan(UList<scalar>&); };