Apparently FreeBSD enables some HW floating-point exceptions by default.

This can cause core dumps when Python runs.  Python relies on the 754-
(and C99-) mandated default "non-stop" mode for FP exceptions.  This
patch from Ben Laurie disables at least one FP exception on FreeBSD at
Python startup time.
This commit is contained in:
Tim Peters 2002-12-28 21:56:08 +00:00
parent 5b26abb37a
commit 4643bd9a9c
3 changed files with 26 additions and 5 deletions

View File

@ -255,10 +255,15 @@ extern "C" {
* if the returned result is a NaN, or if a C89 box returns HUGE_VAL * if the returned result is a NaN, or if a C89 box returns HUGE_VAL
* in non-overflow cases. * in non-overflow cases.
* X is evaluated more than once. * X is evaluated more than once.
* Some platforms have better way to spell this, so expect some #ifdef'ery.
*/ */
#ifdef __FreeBSD__
#define Py_OVERFLOWED(X) isinf(X)
#else
#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \ #define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \
(X) == Py_HUGE_VAL || \ (X) == Py_HUGE_VAL || \
(X) == -Py_HUGE_VAL)) (X) == -Py_HUGE_VAL))
#endif
/* Py_SET_ERANGE_ON_OVERFLOW(x) /* Py_SET_ERANGE_ON_OVERFLOW(x)
* If a libm function did not set errno, but it looks like the result * If a libm function did not set errno, but it looks like the result
@ -320,7 +325,7 @@ extern "C" {
#if defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) #if defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)
#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
#else #else
#define Py_DEPRECATED(VERSION_UNUSED) #define Py_DEPRECATED(VERSION_UNUSED)
#endif #endif
/************************************************************************** /**************************************************************************
@ -395,17 +400,17 @@ extern double hypot(double, double);
/* Declarations for symbol visibility. /* Declarations for symbol visibility.
PyAPI_FUNC(type): Declares a public Python API function and return type PyAPI_FUNC(type): Declares a public Python API function and return type
PyAPI_DATA(type): Declares public Python data and its type PyAPI_DATA(type): Declares public Python data and its type
PyMODINIT_FUNC: A Python module init function. If these functions are PyMODINIT_FUNC: A Python module init function. If these functions are
inside the Python core, they are private to the core. inside the Python core, they are private to the core.
If in an extension module, it may be declared with If in an extension module, it may be declared with
external linkage depending on the platform. external linkage depending on the platform.
As a number of platforms support/require "__declspec(dllimport/dllexport)", As a number of platforms support/require "__declspec(dllimport/dllexport)",
we support a HAVE_DECLSPEC_DLL macro to save duplication. we support a HAVE_DECLSPEC_DLL macro to save duplication.
*/ */
/* /*
All windows ports, except cygwin, are handled in PC/pyconfig.h All windows ports, except cygwin, are handled in PC/pyconfig.h
BeOS is only other autoconf platform requiring special linkage handling BeOS is only other autoconf platform requiring special linkage handling
and both these use __declspec() and both these use __declspec()

View File

@ -303,6 +303,7 @@ Cameron Laird
Detlef Lannert Detlef Lannert
Soren Larsen Soren Larsen
Piers Lauder Piers Lauder
Ben Laurie
Chris Lawrence Chris Lawrence
Christopher Lee Christopher Lee
Inyeol Lee Inyeol Lee

View File

@ -2,8 +2,23 @@
#include "Python.h" #include "Python.h"
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
/* 754 requires that FP exceptions run in "no stop" mode by default,
* and until C vendors implement C99's ways to control FP exceptions,
* Python requires non-stop mode. Alas, some platforms enable FP
* exceptions by default. Here we disable them.
*/
#ifdef __FreeBSD__
fp_except_t m;
m = fpgetmask();
fpsetmask(m & ~FP_X_OFL);
#endif
return Py_Main(argc, argv); return Py_Main(argc, argv);
} }