Adding a FPE-handler for Darwin
--HG-- branch : bgschaid/minorAdditionsBranch
This commit is contained in:
parent
2c4e17cdbf
commit
caf9efd208
4 changed files with 157 additions and 4 deletions
|
@ -45,6 +45,12 @@ License
|
|||
|
||||
# include <sigfpe.h>
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
// # include <fenv.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <mach/mach.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -102,10 +108,40 @@ void* Foam::sigFpe::my_malloc_hook(size_t size, const void *caller)
|
|||
return result;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
void *(*Foam::sigFpe::system_malloc_)(malloc_zone_t *zone, size_t size)=NULL;
|
||||
|
||||
void* Foam::sigFpe::nan_malloc_(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
void *result=system_malloc_(zone,size);
|
||||
|
||||
// initialize to signalling NaN
|
||||
# ifdef WM_SP
|
||||
|
||||
const uint32_t sNAN = 0x7ff7fffflu;
|
||||
uint32_t* dPtr = reinterpret_cast<uint32_t*>(result);
|
||||
|
||||
# else
|
||||
|
||||
const uint64_t sNAN = 0x7ff7ffffffffffffllu;
|
||||
uint64_t* dPtr = reinterpret_cast<uint64_t*>(result);
|
||||
|
||||
# endif
|
||||
|
||||
const size_t nScalars = size/sizeof(scalar);
|
||||
for (size_t i = 0; i < nScalars; ++i)
|
||||
{
|
||||
*dPtr++ = sNAN;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LINUX_GNUC
|
||||
#if defined(LINUX_GNUC) || defined(__APPLE__)
|
||||
|
||||
void Foam::sigFpe::sigFpeHandler(int)
|
||||
{
|
||||
|
@ -170,6 +206,44 @@ Foam::sigFpe::~sigFpe()
|
|||
__malloc_hook = old_malloc_hook;
|
||||
}
|
||||
|
||||
# elif defined(__APPLE__)
|
||||
|
||||
if(system_malloc_!=NULL) {
|
||||
malloc_zone_t *zone = malloc_default_zone();
|
||||
if(zone==NULL) {
|
||||
FatalErrorIn("Foam__sigFpe::set")
|
||||
<< "Could not get malloc_default_zone()." << endl
|
||||
<< "Seems like this version of Mac OS X doesn't support FOAM_SETNAN"
|
||||
<< endl
|
||||
<< exit(FatalError);
|
||||
|
||||
}
|
||||
|
||||
if(zone->version>=8)
|
||||
{
|
||||
vm_protect(
|
||||
mach_task_self(),
|
||||
(uintptr_t)zone,
|
||||
sizeof(malloc_zone_t),
|
||||
0,
|
||||
VM_PROT_READ | VM_PROT_WRITE
|
||||
);//remove the write protection
|
||||
}
|
||||
zone->malloc=system_malloc_;
|
||||
system_malloc_=NULL;
|
||||
if(zone->version==8)
|
||||
{
|
||||
vm_protect(
|
||||
mach_task_self(),
|
||||
(uintptr_t)zone,
|
||||
sizeof(malloc_zone_t),
|
||||
0,
|
||||
VM_PROT_READ
|
||||
);//put the write protection back
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
@ -240,6 +314,26 @@ void Foam::sigFpe::set(const bool verbose)
|
|||
NULL
|
||||
);
|
||||
|
||||
# elif defined(__APPLE__)
|
||||
|
||||
struct sigaction newAction;
|
||||
newAction.sa_handler = sigFpeHandler;
|
||||
newAction.sa_flags = SA_NODEFER;
|
||||
sigemptyset(&newAction.sa_mask);
|
||||
if (sigaction(SIGFPE, &newAction, &oldAction_) < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Foam::sigFpe::set()"
|
||||
) << "Cannot set SIGFPE trapping"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID);
|
||||
_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_DIV_ZERO);
|
||||
|
||||
_mm_setcsr( _MM_MASK_MASK &~
|
||||
(_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO) );
|
||||
|
||||
# endif
|
||||
}
|
||||
|
||||
|
@ -257,6 +351,48 @@ void Foam::sigFpe::set(const bool verbose)
|
|||
// Set our malloc
|
||||
__malloc_hook = Foam::sigFpe::my_malloc_hook;
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
if(system_malloc_!=NULL) {
|
||||
FatalErrorIn("Foam__sigFpe::set")
|
||||
<< "system_malloc_ already reset." << endl
|
||||
<< "This should never happen"
|
||||
<< endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
malloc_zone_t *zone = malloc_default_zone();
|
||||
if(zone==NULL) {
|
||||
FatalErrorIn("Foam__sigFpe::set")
|
||||
<< "Could not get malloc_default_zone()." << endl
|
||||
<< "Seems like this version of Mac OS X doesn't support FOAM_SETNAN"
|
||||
<< endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
// According to http://bkdc.ubiquity.ro/2011/07/how-to-set-malloc-hooks-in-osx-lion-107.html
|
||||
if(zone->version>=8)
|
||||
{
|
||||
vm_protect(
|
||||
mach_task_self(),
|
||||
(uintptr_t)zone,
|
||||
sizeof(malloc_zone_t),
|
||||
0,
|
||||
VM_PROT_READ | VM_PROT_WRITE
|
||||
);//remove the write protection
|
||||
}
|
||||
system_malloc_=zone->malloc;
|
||||
zone->malloc=Foam::sigFpe::nan_malloc_;
|
||||
if(zone->version==8)
|
||||
{
|
||||
vm_protect(
|
||||
mach_task_self(),
|
||||
(uintptr_t)zone,
|
||||
sizeof(malloc_zone_t),
|
||||
0,
|
||||
VM_PROT_READ
|
||||
);//put the write protection back
|
||||
}
|
||||
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,15 @@ SourceFiles
|
|||
# define LINUX_GNUC
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <malloc/malloc.h>
|
||||
|
||||
// these are defined by the mach-headers and would break compilation of Switch.H
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
|
@ -79,12 +88,20 @@ class sigFpe
|
|||
//- nan malloc function. From malloc_hook manpage.
|
||||
static void* my_malloc_hook(size_t size, const void *caller);
|
||||
|
||||
#elif defined (__APPLE__)
|
||||
|
||||
//- pointer to the original malloc that is overrided
|
||||
static void *(*system_malloc_)(malloc_zone_t *zone, size_t size);
|
||||
|
||||
//- the overriding handler
|
||||
static void* nan_malloc_(malloc_zone_t *zone, size_t size);
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
// Static data members
|
||||
|
||||
# ifdef LINUX_GNUC
|
||||
# if defined(LINUX_GNUC) || defined(__APPLE__)
|
||||
|
||||
//- Handler for caught signals
|
||||
static void sigFpeHandler(int);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
cWARN = -Wall
|
||||
|
||||
cc = $(WM_CC) $(WM_CXXFLAGS)
|
||||
cc = $(WM_CC) $(WM_CXXFLAGS) -fsignaling-nans -ftrapping-math
|
||||
|
||||
include $(RULES)/c$(WM_COMPILE_OPTION)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
c++WARN = -Wall -Wextra -Wno-unused-parameter -Wold-style-cast -Wno-overloaded-virtual -Wno-unsequenced -Wno-c++11-extensions -Wno-unused-comparison
|
||||
|
||||
CC = $(WM_CXX) $(WM_CXXFLAGS)
|
||||
CC = $(WM_CXX) $(WM_CXXFLAGS) -fsignaling-nans -ftrapping-math
|
||||
|
||||
include $(RULES)/c++$(WM_COMPILE_OPTION)
|
||||
|
||||
|
|
Reference in a new issue