Commit 00279d61 authored by Henry Weller's avatar Henry Weller
Browse files

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.
parent a316fa6a
......@@ -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;
......
......@@ -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>&);
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment