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>
|
# include <sigfpe.h>
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
|
// # include <fenv.h>
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,10 +108,40 @@ void* Foam::sigFpe::my_malloc_hook(size_t size, const void *caller)
|
||||||
return result;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef LINUX_GNUC
|
#if defined(LINUX_GNUC) || defined(__APPLE__)
|
||||||
|
|
||||||
void Foam::sigFpe::sigFpeHandler(int)
|
void Foam::sigFpe::sigFpeHandler(int)
|
||||||
{
|
{
|
||||||
|
@ -170,6 +206,44 @@ Foam::sigFpe::~sigFpe()
|
||||||
__malloc_hook = old_malloc_hook;
|
__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
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,6 +314,26 @@ void Foam::sigFpe::set(const bool verbose)
|
||||||
NULL
|
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
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +351,48 @@ void Foam::sigFpe::set(const bool verbose)
|
||||||
// Set our malloc
|
// Set our malloc
|
||||||
__malloc_hook = Foam::sigFpe::my_malloc_hook;
|
__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
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,15 @@ SourceFiles
|
||||||
# define LINUX_GNUC
|
# define LINUX_GNUC
|
||||||
#endif
|
#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
|
namespace Foam
|
||||||
|
@ -79,12 +88,20 @@ class sigFpe
|
||||||
//- nan malloc function. From malloc_hook manpage.
|
//- nan malloc function. From malloc_hook manpage.
|
||||||
static void* my_malloc_hook(size_t size, const void *caller);
|
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
|
# endif
|
||||||
|
|
||||||
|
|
||||||
// Static data members
|
// Static data members
|
||||||
|
|
||||||
# ifdef LINUX_GNUC
|
# if defined(LINUX_GNUC) || defined(__APPLE__)
|
||||||
|
|
||||||
//- Handler for caught signals
|
//- Handler for caught signals
|
||||||
static void sigFpeHandler(int);
|
static void sigFpeHandler(int);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
cWARN = -Wall
|
cWARN = -Wall
|
||||||
|
|
||||||
cc = $(WM_CC) $(WM_CXXFLAGS)
|
cc = $(WM_CC) $(WM_CXXFLAGS) -fsignaling-nans -ftrapping-math
|
||||||
|
|
||||||
include $(RULES)/c$(WM_COMPILE_OPTION)
|
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
|
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)
|
include $(RULES)/c++$(WM_COMPILE_OPTION)
|
||||||
|
|
||||||
|
|
Reference in a new issue