mirror of
https://github.com/OpenFOAM/OpenFOAM-6.git
synced 2025-12-08 06:57:46 +00:00
sigFpe: Replace the deprecated __malloc_hook with a special malloc
This malloc overrides the one provided by GLIBC and calls mallocNan which initializes the allocated block of memory to NaN if enabled by the FOAM_SETNAN environment variable.
This commit is contained in:
@ -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)
|
||||
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;
|
||||
|
||||
@ -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>&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user