bpo-29137: Remove fpectl module (#4789)

This module has never been enabled by default, never worked correctly
on x86-64, and caused ABI problems that caused C extension
compatibility. See bpo-29137 for details/discussion.
This commit is contained in:
Nathaniel J. Smith 2018-01-05 23:15:34 -08:00 committed by Benjamin Peterson
parent 502d551c6d
commit 735ae8d139
14 changed files with 19 additions and 865 deletions

View File

@ -154,10 +154,7 @@ The following exceptions are the exceptions that are usually raised.
.. exception:: FloatingPointError .. exception:: FloatingPointError
Raised when a floating point operation fails. This exception is always defined, Not currently used.
but can only be raised when Python is configured with the
``--with-fpectl`` option, or the :const:`WANT_SIGFPE_HANDLER` symbol is
defined in the :file:`pyconfig.h` file.
.. exception:: GeneratorExit .. exception:: GeneratorExit

View File

@ -1,121 +0,0 @@
:mod:`fpectl` --- Floating point exception control
==================================================
.. module:: fpectl
:platform: Unix
:synopsis: Provide control for floating point exception handling.
.. moduleauthor:: Lee Busby <busby1@llnl.gov>
.. sectionauthor:: Lee Busby <busby1@llnl.gov>
.. note::
The :mod:`fpectl` module is not built by default, and its usage is discouraged
and may be dangerous except in the hands of experts. See also the section
:ref:`fpectl-limitations` on limitations for more details.
.. index:: single: IEEE-754
--------------
Most computers carry out floating point operations in conformance with the
so-called IEEE-754 standard. On any real computer, some floating point
operations produce results that cannot be expressed as a normal floating point
value. For example, try ::
>>> import math
>>> math.exp(1000)
inf
>>> math.exp(1000) / math.exp(1000)
nan
(The example above will work on many platforms. DEC Alpha may be one exception.)
"Inf" is a special, non-numeric value in IEEE-754 that stands for "infinity",
and "nan" means "not a number." Note that, other than the non-numeric results,
nothing special happened when you asked Python to carry out those calculations.
That is in fact the default behaviour prescribed in the IEEE-754 standard, and
if it works for you, stop reading now.
In some circumstances, it would be better to raise an exception and stop
processing at the point where the faulty operation was attempted. The
:mod:`fpectl` module is for use in that situation. It provides control over
floating point units from several hardware manufacturers, allowing the user to
turn on the generation of :const:`SIGFPE` whenever any of the IEEE-754
exceptions Division by Zero, Overflow, or Invalid Operation occurs. In tandem
with a pair of wrapper macros that are inserted into the C code comprising your
python system, :const:`SIGFPE` is trapped and converted into the Python
:exc:`FloatingPointError` exception.
The :mod:`fpectl` module defines the following functions and may raise the given
exception:
.. function:: turnon_sigfpe()
Turn on the generation of :const:`SIGFPE`, and set up an appropriate signal
handler.
.. function:: turnoff_sigfpe()
Reset default handling of floating point exceptions.
.. exception:: FloatingPointError
After :func:`turnon_sigfpe` has been executed, a floating point operation that
raises one of the IEEE-754 exceptions Division by Zero, Overflow, or Invalid
operation will in turn raise this standard Python exception.
.. _fpectl-example:
Example
-------
The following example demonstrates how to start up and test operation of the
:mod:`fpectl` module. ::
>>> import fpectl
>>> import fpetest
>>> fpectl.turnon_sigfpe()
>>> fpetest.test()
overflow PASS
FloatingPointError: Overflow
div by 0 PASS
FloatingPointError: Division by zero
[ more output from test elided ]
>>> import math
>>> math.exp(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FloatingPointError: in math_1
.. _fpectl-limitations:
Limitations and other considerations
------------------------------------
Setting up a given processor to trap IEEE-754 floating point errors currently
requires custom code on a per-architecture basis. You may have to modify
:mod:`fpectl` to control your particular hardware.
Conversion of an IEEE-754 exception to a Python exception requires that the
wrapper macros ``PyFPE_START_PROTECT`` and ``PyFPE_END_PROTECT`` be inserted
into your code in an appropriate fashion. Python itself has been modified to
support the :mod:`fpectl` module, but many other codes of interest to numerical
analysts have not.
The :mod:`fpectl` module is not thread-safe.
.. seealso::
Some files in the source distribution may be interesting in learning more about
how this module operates. The include file :file:`Include/pyfpe.h` discusses the
implementation of this module at some length. :file:`Modules/fpetestmodule.c`
gives several examples of use. Many additional examples can be found in
:file:`Objects/floatobject.c`.

View File

@ -24,4 +24,3 @@ overview:
gc.rst gc.rst
inspect.rst inspect.rst
site.rst site.rst
fpectl.rst

View File

@ -349,48 +349,6 @@ Project, http://www.wide.ad.jp/. ::
SUCH DAMAGE. SUCH DAMAGE.
Floating point exception control
--------------------------------
The source for the :mod:`fpectl` module includes the following notice::
---------------------------------------------------------------------
/ Copyright (c) 1996. \
| The Regents of the University of California. |
| All rights reserved. |
| |
| Permission to use, copy, modify, and distribute this software for |
| any purpose without fee is hereby granted, provided that this en- |
| tire notice is included in all copies of any software which is or |
| includes a copy or modification of this software and in all |
| copies of the supporting documentation for such software. |
| |
| This work was produced at the University of California, Lawrence |
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
| between the U.S. Department of Energy and The Regents of the |
| University of California for the operation of UC LLNL. |
| |
| DISCLAIMER |
| |
| This software was prepared as an account of work sponsored by an |
| agency of the United States Government. Neither the United States |
| Government nor the University of California nor any of their em- |
| ployees, makes any warranty, express or implied, or assumes any |
| liability or responsibility for the accuracy, completeness, or |
| usefulness of any information, apparatus, product, or process |
| disclosed, or represents that its use would not infringe |
| privately-owned rights. Reference herein to any specific commer- |
| cial products, process, or service by trade name, trademark, |
| manufacturer, or otherwise, does not necessarily constitute or |
| imply its endorsement, recommendation, or favoring by the United |
| States Government or the University of California. The views and |
| opinions of authors expressed herein do not necessarily state or |
| reflect those of the United States Government or the University |
| of California, and shall not be used for advertising or product |
\ endorsement purposes. /
---------------------------------------------------------------------
Asynchronous socket services Asynchronous socket services
---------------------------- ----------------------------

View File

@ -1,176 +1,12 @@
#ifndef Py_PYFPE_H #ifndef Py_PYFPE_H
#define Py_PYFPE_H #define Py_PYFPE_H
#ifdef __cplusplus
extern "C" { /* These macros used to do something when Python was built with --with-fpectl,
#endif * but support for that was dropped in 3.7. We continue to define them though,
/* * to avoid breaking API users.
---------------------------------------------------------------------
/ Copyright (c) 1996. \
| The Regents of the University of California. |
| All rights reserved. |
| |
| Permission to use, copy, modify, and distribute this software for |
| any purpose without fee is hereby granted, provided that this en- |
| tire notice is included in all copies of any software which is or |
| includes a copy or modification of this software and in all |
| copies of the supporting documentation for such software. |
| |
| This work was produced at the University of California, Lawrence |
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
| between the U.S. Department of Energy and The Regents of the |
| University of California for the operation of UC LLNL. |
| |
| DISCLAIMER |
| |
| This software was prepared as an account of work sponsored by an |
| agency of the United States Government. Neither the United States |
| Government nor the University of California nor any of their em- |
| ployees, makes any warranty, express or implied, or assumes any |
| liability or responsibility for the accuracy, completeness, or |
| usefulness of any information, apparatus, product, or process |
| disclosed, or represents that its use would not infringe |
| privately-owned rights. Reference herein to any specific commer- |
| cial products, process, or service by trade name, trademark, |
| manufacturer, or otherwise, does not necessarily constitute or |
| imply its endorsement, recommendation, or favoring by the United |
| States Government or the University of California. The views and |
| opinions of authors expressed herein do not necessarily state or |
| reflect those of the United States Government or the University |
| of California, and shall not be used for advertising or product |
\ endorsement purposes. /
---------------------------------------------------------------------
*/ */
/*
* Define macros for handling SIGFPE.
* Lee Busby, LLNL, November, 1996
* busby1@llnl.gov
*
*********************************************
* Overview of the system for handling SIGFPE:
*
* This file (Include/pyfpe.h) defines a couple of "wrapper" macros for
* insertion into your Python C code of choice. Their proper use is
* discussed below. The file Python/pyfpe.c defines a pair of global
* variables PyFPE_jbuf and PyFPE_counter which are used by the signal
* handler for SIGFPE to decide if a particular exception was protected
* by the macros. The signal handler itself, and code for enabling the
* generation of SIGFPE in the first place, is in a (new) Python module
* named fpectl. This module is standard in every respect. It can be loaded
* either statically or dynamically as you choose, and like any other
* Python module, has no effect until you import it.
*
* In the general case, there are three steps toward handling SIGFPE in any
* Python code:
*
* 1) Add the *_PROTECT macros to your C code as required to protect
* dangerous floating point sections.
*
* 2) Turn on the inclusion of the code by adding the ``--with-fpectl''
* flag at the time you run configure. If the fpectl or other modules
* which use the *_PROTECT macros are to be dynamically loaded, be
* sure they are compiled with WANT_SIGFPE_HANDLER defined.
*
* 3) When python is built and running, import fpectl, and execute
* fpectl.turnon_sigfpe(). This sets up the signal handler and enables
* generation of SIGFPE whenever an exception occurs. From this point
* on, any properly trapped SIGFPE should result in the Python
* FloatingPointError exception.
*
* Step 1 has been done already for the Python kernel code, and should be
* done soon for the NumPy array package. Step 2 is usually done once at
* python install time. Python's behavior with respect to SIGFPE is not
* changed unless you also do step 3. Thus you can control this new
* facility at compile time, or run time, or both.
*
********************************
* Using the macros in your code:
*
* static PyObject *foobar(PyObject *self,PyObject *args)
* {
* ....
* PyFPE_START_PROTECT("Error in foobar", return 0)
* result = dangerous_op(somearg1, somearg2, ...);
* PyFPE_END_PROTECT(result)
* ....
* }
*
* If a floating point error occurs in dangerous_op, foobar returns 0 (NULL),
* after setting the associated value of the FloatingPointError exception to
* "Error in foobar". ``Dangerous_op'' can be a single operation, or a block
* of code, function calls, or any combination, so long as no alternate
* return is possible before the PyFPE_END_PROTECT macro is reached.
*
* The macros can only be used in a function context where an error return
* can be recognized as signaling a Python exception. (Generally, most
* functions that return a PyObject * will qualify.)
*
* Guido's original design suggestion for PyFPE_START_PROTECT and
* PyFPE_END_PROTECT had them open and close a local block, with a locally
* defined jmp_buf and jmp_buf pointer. This would allow recursive nesting
* of the macros. The Ansi C standard makes it clear that such local
* variables need to be declared with the "volatile" type qualifier to keep
* setjmp from corrupting their values. Some current implementations seem
* to be more restrictive. For example, the HPUX man page for setjmp says
*
* Upon the return from a setjmp() call caused by a longjmp(), the
* values of any non-static local variables belonging to the routine
* from which setjmp() was called are undefined. Code which depends on
* such values is not guaranteed to be portable.
*
* I therefore decided on a more limited form of nesting, using a counter
* variable (PyFPE_counter) to keep track of any recursion. If an exception
* occurs in an ``inner'' pair of macros, the return will apparently
* come from the outermost level.
*
*/
#ifdef WANT_SIGFPE_HANDLER
#include <signal.h>
#include <setjmp.h>
#include <math.h>
extern jmp_buf PyFPE_jbuf;
extern int PyFPE_counter;
extern double PyFPE_dummy(void *);
#define PyFPE_START_PROTECT(err_string, leave_stmt) \
if (!PyFPE_counter++ && setjmp(PyFPE_jbuf)) { \
PyErr_SetString(PyExc_FloatingPointError, err_string); \
PyFPE_counter = 0; \
leave_stmt; \
}
/*
* This (following) is a heck of a way to decrement a counter. However,
* unless the macro argument is provided, code optimizers will sometimes move
* this statement so that it gets executed *before* the unsafe expression
* which we're trying to protect. That pretty well messes things up,
* of course.
*
* If the expression(s) you're trying to protect don't happen to return a
* value, you will need to manufacture a dummy result just to preserve the
* correct ordering of statements. Note that the macro passes the address
* of its argument (so you need to give it something which is addressable).
* If your expression returns multiple results, pass the last such result
* to PyFPE_END_PROTECT.
*
* Note that PyFPE_dummy returns a double, which is cast to int.
* This seeming insanity is to tickle the Floating Point Unit (FPU).
* If an exception has occurred in a preceding floating point operation,
* some architectures (notably Intel 80x86) will not deliver the interrupt
* until the *next* floating point operation. This is painful if you've
* already decremented PyFPE_counter.
*/
#define PyFPE_END_PROTECT(v) PyFPE_counter -= (int)PyFPE_dummy(&(v));
#else
#define PyFPE_START_PROTECT(err_string, leave_stmt) #define PyFPE_START_PROTECT(err_string, leave_stmt)
#define PyFPE_END_PROTECT(v) #define PyFPE_END_PROTECT(v)
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_PYFPE_H */ #endif /* !Py_PYFPE_H */

View File

@ -0,0 +1,3 @@
The ``fpectl`` library has been removed. It was never enabled by default,
never worked correctly on x86-64, and it changed the Python ABI in ways that
caused unexpected breakage of C extensions.

View File

@ -334,20 +334,6 @@ _symtable symtablemodule.c
#parser parsermodule.c #parser parsermodule.c
# Lee Busby's SIGFPE modules.
# The library to link fpectl with is platform specific.
# Choose *one* of the options below for fpectl:
# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
# (Without the compiler you don't have -lsunmath.)
#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
# For other systems: see instructions in fpectlmodule.c.
#fpectl fpectlmodule.c ...
# Test module for fpectl. No extra libraries needed.
#fpetest fpetestmodule.c
# Andrew Kuchling's zlib module. # Andrew Kuchling's zlib module.
# This require zlib 1.1.3 (or later). # This require zlib 1.1.3 (or later).
# See http://www.gzip.org/zlib/ # See http://www.gzip.org/zlib/

View File

@ -1,255 +0,0 @@
/*
---------------------------------------------------------------------
/ Copyright (c) 1996. \
| The Regents of the University of California. |
| All rights reserved. |
| |
| Permission to use, copy, modify, and distribute this software for |
| any purpose without fee is hereby granted, provided that this en- |
| tire notice is included in all copies of any software which is or |
| includes a copy or modification of this software and in all |
| copies of the supporting documentation for such software. |
| |
| This work was produced at the University of California, Lawrence |
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
| between the U.S. Department of Energy and The Regents of the |
| University of California for the operation of UC LLNL. |
| |
| DISCLAIMER |
| |
| This software was prepared as an account of work sponsored by an |
| agency of the United States Government. Neither the United States |
| Government nor the University of California nor any of their em- |
| ployees, makes any warranty, express or implied, or assumes any |
| liability or responsibility for the accuracy, completeness, or |
| usefulness of any information, apparatus, product, or process |
| disclosed, or represents that its use would not infringe |
| privately-owned rights. Reference herein to any specific commer- |
| cial products, process, or service by trade name, trademark, |
| manufacturer, or otherwise, does not necessarily constitute or |
| imply its endorsement, recommendation, or favoring by the United |
| States Government or the University of California. The views and |
| opinions of authors expressed herein do not necessarily state or |
| reflect those of the United States Government or the University |
| of California, and shall not be used for advertising or product |
\ endorsement purposes. /
---------------------------------------------------------------------
*/
/*
Floating point exception control module.
This Python module provides bare-bones control over floating point
units from several hardware manufacturers. Specifically, it allows
the user to turn on the generation of SIGFPE whenever any of the
three serious IEEE 754 exceptions (Division by Zero, Overflow,
Invalid Operation) occurs. We currently ignore Underflow and
Inexact Result exceptions, although those could certainly be added
if desired.
The module also establishes a signal handler for SIGFPE during
initialization. This builds on code found in the Python
distribution at Include/pyfpe.h and Python/pyfpe.c. If those files
are not in your Python distribution, find them in a patch at
ftp://icf.llnl.gov/pub/python/busby/patches.961108.tgz.
This module is only useful to you if it happens to include code
specific for your hardware and software environment. If you can
contribute OS-specific code for new platforms, or corrections for
the code provided, it will be greatly appreciated.
** Version 1.0: September 20, 1996. Lee Busby, LLNL.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "Python.h"
#include <signal.h>
#if defined(__FreeBSD__)
# include <ieeefp.h>
#endif
#ifndef WANT_SIGFPE_HANDLER
/* Define locally if they are not defined in Python. This gives only
* the limited control to induce a core dump in case of an exception.
*/
#include <setjmp.h>
static jmp_buf PyFPE_jbuf;
static int PyFPE_counter = 0;
#endif
typedef void Sigfunc(int);
static Sigfunc sigfpe_handler;
static void fpe_reset(Sigfunc *);
static PyObject *fpe_error;
PyMODINIT_FUNC PyInit_fpectl(void);
static PyObject *turnon_sigfpe (PyObject *self,PyObject *args);
static PyObject *turnoff_sigfpe (PyObject *self,PyObject *args);
static PyMethodDef fpectl_methods[] = {
{"turnon_sigfpe", (PyCFunction) turnon_sigfpe, METH_VARARGS},
{"turnoff_sigfpe", (PyCFunction) turnoff_sigfpe, METH_VARARGS},
{0,0}
};
static PyObject *turnon_sigfpe(PyObject *self,PyObject *args)
{
/* Do any architecture-specific one-time only initialization here. */
fpe_reset(sigfpe_handler);
Py_RETURN_NONE;
}
static void fpe_reset(Sigfunc *handler)
{
/* Reset the exception handling machinery, and reset the signal
* handler for SIGFPE to the given handler.
*/
/*-- SunOS and Solaris ----------------------------------------------------*/
#if defined(sun)
/* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags
man pages (SunOS or Solaris)
cc -c -I/usr/local/python/include fpectlmodule.c
ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm
*/
#include <math.h>
#ifndef _SUNMATH_H
extern void nonstandard_arithmetic(void);
extern int ieee_flags(const char*, const char*, const char*, char **);
extern long ieee_handler(const char*, const char*, sigfpe_handler_type);
#endif
const char *mode="exception", *in="all";
char *out;
(void) nonstandard_arithmetic();
(void) ieee_flags("clearall",mode,in,&out);
(void) ieee_handler("set","common",(sigfpe_handler_type)handler);
PyOS_setsig(SIGFPE, handler);
/*-- HPUX -----------------------------------------------------------------*/
#elif defined(__hppa) || defined(hppa)
/* References: fpsetmask man page */
/* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */
/* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */
#include <math.h>
fpsetdefaults();
PyOS_setsig(SIGFPE, handler);
/*-- IBM AIX --------------------------------------------------------------*/
#elif defined(__AIX) || defined(_AIX)
/* References: fp_trap, fp_enable man pages */
#include <fptrap.h>
fp_trap(FP_TRAP_SYNC);
fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
PyOS_setsig(SIGFPE, handler);
/*-- DEC ALPHA LINUX ------------------------------------------------------*/
#elif defined(__alpha) && defined(linux)
#include <asm/fpu.h>
unsigned long fp_control =
IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
ieee_set_fp_control(fp_control);
PyOS_setsig(SIGFPE, handler);
/*-- Cray Unicos ----------------------------------------------------------*/
#elif defined(cray)
/* UNICOS delivers SIGFPE by default, but no matherr */
#ifdef HAS_LIBMSET
libmset(-1);
#endif
PyOS_setsig(SIGFPE, handler);
/*-- FreeBSD ----------------------------------------------------------------*/
#elif defined(__FreeBSD__)
fpresetsticky(fpgetsticky());
fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL);
PyOS_setsig(SIGFPE, handler);
/*-- Linux ----------------------------------------------------------------*/
#elif defined(linux)
#ifdef __GLIBC__
#include <fpu_control.h>
#else
#include <i386/fpu_control.h>
#endif
#ifdef _FPU_SETCW
{
fpu_control_t cw = 0x1372;
_FPU_SETCW(cw);
}
#else
__setfpucw(0x1372);
#endif
PyOS_setsig(SIGFPE, handler);
/*-- Microsoft Windows, NT ------------------------------------------------*/
#elif defined(_MSC_VER)
/* Reference: Visual C++ Books Online 4.2,
Run-Time Library Reference, _control87, _controlfp */
#include <float.h>
unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW;
(void)_controlfp(0, cw);
PyOS_setsig(SIGFPE, handler);
/*-- Give Up --------------------------------------------------------------*/
#else
fputs("Operation not implemented\n", stderr);
#endif
}
static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
{
#ifdef __FreeBSD__
fpresetsticky(fpgetsticky());
fpsetmask(0);
#else
fputs("Operation not implemented\n", stderr);
#endif
Py_RETURN_NONE;
}
static void sigfpe_handler(int signo)
{
fpe_reset(sigfpe_handler);
if(PyFPE_counter) {
longjmp(PyFPE_jbuf, 1);
} else {
Py_FatalError("Unprotected floating point exception");
}
}
static struct PyModuleDef fpectlmodule = {
PyModuleDef_HEAD_INIT,
"fpectl",
NULL,
-1,
fpectl_methods,
NULL,
NULL,
NULL,
NULL
};
PyMODINIT_FUNC PyInit_fpectl(void)
{
PyObject *m, *d;
m = PyModule_Create(&fpectlmodule);
if (m == NULL)
return NULL;
d = PyModule_GetDict(m);
fpe_error = PyErr_NewException("fpectl.error", NULL, NULL);
if (fpe_error != NULL)
PyDict_SetItemString(d, "error", fpe_error);
return m;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,199 +0,0 @@
/*
---------------------------------------------------------------------
/ Copyright (c) 1996. \
| The Regents of the University of California. |
| All rights reserved. |
| |
| Permission to use, copy, modify, and distribute this software for |
| any purpose without fee is hereby granted, provided that this en- |
| tire notice is included in all copies of any software which is or |
| includes a copy or modification of this software and in all |
| copies of the supporting documentation for such software. |
| |
| This work was produced at the University of California, Lawrence |
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
| between the U.S. Department of Energy and The Regents of the |
| University of California for the operation of UC LLNL. |
| |
| DISCLAIMER |
| |
| This software was prepared as an account of work sponsored by an |
| agency of the United States Government. Neither the United States |
| Government nor the University of California nor any of their em- |
| ployees, makes any warranty, express or implied, or assumes any |
| liability or responsibility for the accuracy, completeness, or |
| usefulness of any information, apparatus, product, or process |
| disclosed, or represents that its use would not infringe |
| privately-owned rights. Reference herein to any specific commer- |
| cial products, process, or service by trade name, trademark, |
| manufacturer, or otherwise, does not necessarily constitute or |
| imply its endorsement, recommendation, or favoring by the United |
| States Government or the University of California. The views and |
| opinions of authors expressed herein do not necessarily state or |
| reflect those of the United States Government or the University |
| of California, and shall not be used for advertising or product |
\ endorsement purposes. /
---------------------------------------------------------------------
*/
/*
Floating point exception test module.
*/
#include "Python.h"
static PyObject *fpe_error;
PyMODINIT_FUNC PyInit_fpetest(void);
static PyObject *test(PyObject *self,PyObject *args);
static double db0(double);
static double overflow(double);
static double nest1(int, double);
static double nest2(int, double);
static double nest3(double);
static void printerr(double);
static PyMethodDef fpetest_methods[] = {
{"test", (PyCFunction) test, METH_VARARGS},
{0,0}
};
static PyObject *test(PyObject *self,PyObject *args)
{
double r;
fprintf(stderr,"overflow");
r = overflow(1.e160);
printerr(r);
fprintf(stderr,"\ndiv by 0");
r = db0(0.0);
printerr(r);
fprintf(stderr,"\nnested outer");
r = nest1(0, 0.0);
printerr(r);
fprintf(stderr,"\nnested inner");
r = nest1(1, 1.0);
printerr(r);
fprintf(stderr,"\ntrailing outer");
r = nest1(2, 2.0);
printerr(r);
fprintf(stderr,"\nnested prior");
r = nest2(0, 0.0);
printerr(r);
fprintf(stderr,"\nnested interior");
r = nest2(1, 1.0);
printerr(r);
fprintf(stderr,"\nnested trailing");
r = nest2(2, 2.0);
printerr(r);
Py_RETURN_NONE;
}
static void printerr(double r)
{
if(r == 3.1416){
fprintf(stderr,"\tPASS\n");
PyErr_Print();
}else{
fprintf(stderr,"\tFAIL\n");
}
PyErr_Clear();
}
static double nest1(int i, double x)
{
double a = 1.0;
PyFPE_START_PROTECT("Division by zero, outer zone", return 3.1416)
if(i == 0){
a = 1./x;
}else if(i == 1){
/* This (following) message is never seen. */
PyFPE_START_PROTECT("Division by zero, inner zone", return 3.1416)
a = 1./(1. - x);
PyFPE_END_PROTECT(a)
}else if(i == 2){
a = 1./(2. - x);
}
PyFPE_END_PROTECT(a)
return a;
}
static double nest2(int i, double x)
{
double a = 1.0;
PyFPE_START_PROTECT("Division by zero, prior error", return 3.1416)
if(i == 0){
a = 1./x;
}else if(i == 1){
a = nest3(x);
}else if(i == 2){
a = 1./(2. - x);
}
PyFPE_END_PROTECT(a)
return a;
}
static double nest3(double x)
{
double result;
/* This (following) message is never seen. */
PyFPE_START_PROTECT("Division by zero, nest3 error", return 3.1416)
result = 1./(1. - x);
PyFPE_END_PROTECT(result)
return result;
}
static double db0(double x)
{
double a;
PyFPE_START_PROTECT("Division by zero", return 3.1416)
a = 1./x;
PyFPE_END_PROTECT(a)
return a;
}
static double overflow(double b)
{
double a;
PyFPE_START_PROTECT("Overflow", return 3.1416)
a = b*b;
PyFPE_END_PROTECT(a)
return a;
}
static struct PyModuleDef fpetestmodule = {
PyModuleDef_HEAD_INIT,
"fpetest",
NULL,
-1,
fpetest_methods,
NULL,
NULL,
NULL,
NULL
};
PyMODINIT_FUNC PyInit_fpetest(void)
{
PyObject *m, *d;
m = PyModule_Create(&fpetestmodule);
if (m == NULL)
return NULL;
d = PyModule_GetDict(m);
fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
if (fpe_error != NULL)
PyDict_SetItemString(d, "error", fpe_error);
return m;
}

View File

@ -1,20 +1,12 @@
#include "pyconfig.h" /* These variables used to be used when Python was built with --with-fpectl,
#include "pyfpe.h" * but support for that was dropped in 3.7. We continue to define them,
/* * though, because they may be referenced by extensions using the stable ABI.
* The signal handler for SIGFPE is actually declared in an external
* module fpectl, or as preferred by the user. These variable
* definitions are required in order to compile Python without
* getting missing externals, but to actually handle SIGFPE requires
* defining a handler and enabling generation of SIGFPE.
*/ */
#ifdef WANT_SIGFPE_HANDLER #include "setjmp.h"
jmp_buf PyFPE_jbuf;
int PyFPE_counter = 0;
#endif
/* Have this outside the above #ifdef, since some picky ANSI compilers issue a jmp_buf PyFPE_jbuf;
warning when compiling an empty file. */ int PyFPE_counter;
double double
PyFPE_dummy(void *dummy) PyFPE_dummy(void *dummy)

8
aclocal.m4 vendored
View File

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15 -*- Autoconf -*- # generated automatically by aclocal 1.15.1 -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Copyright (C) 1996-2017 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -13,7 +13,7 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29.1) dnl serial 11 (pkg-config-0.29)
dnl dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@ -55,7 +55,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1]) [m4_define([PKG_MACROS_VERSION], [0.29])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ

25
configure vendored
View File

@ -832,7 +832,6 @@ with_c_locale_coercion
with_c_locale_warning with_c_locale_warning
with_valgrind with_valgrind
with_dtrace with_dtrace
with_fpectl
with_libm with_libm
with_libc with_libc
enable_big_digits enable_big_digits
@ -1539,7 +1538,6 @@ Optional Packages:
locale locale
--with-valgrind Enable Valgrind support --with-valgrind Enable Valgrind support
--with(out)-dtrace disable/enable DTrace support --with(out)-dtrace disable/enable DTrace support
--with-fpectl enable SIGFPE catching
--with-libm=STRING math library --with-libm=STRING math library
--with-libc=STRING C library --with-libc=STRING C library
--with(out)-computed-gotos --with(out)-computed-gotos
@ -13691,29 +13689,6 @@ fi
fi fi
# Check for --with-fpectl
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-fpectl" >&5
$as_echo_n "checking for --with-fpectl... " >&6; }
# Check whether --with-fpectl was given.
if test "${with_fpectl+set}" = set; then :
withval=$with_fpectl;
if test "$withval" != no
then
$as_echo "#define WANT_SIGFPE_HANDLER 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# check for --with-libm=... # check for --with-libm=...
case $ac_sys_system in case $ac_sys_system in

View File

@ -4135,20 +4135,6 @@ AC_CHECK_FUNC(__fpu_control,
[AC_CHECK_LIB(ieee, __fpu_control) [AC_CHECK_LIB(ieee, __fpu_control)
]) ])
# Check for --with-fpectl
AC_MSG_CHECKING(for --with-fpectl)
AC_ARG_WITH(fpectl,
AS_HELP_STRING([--with-fpectl], [enable SIGFPE catching]),
[
if test "$withval" != no
then
AC_DEFINE(WANT_SIGFPE_HANDLER, 1,
[Define if you want SIGFPE handled (see Include/pyfpe.h).])
AC_MSG_RESULT(yes)
else AC_MSG_RESULT(no)
fi],
[AC_MSG_RESULT(no)])
# check for --with-libm=... # check for --with-libm=...
AC_SUBST(LIBM) AC_SUBST(LIBM)
case $ac_sys_system in case $ac_sys_system in

View File

@ -500,7 +500,7 @@
/* Define to 1 if you have the <ieeefp.h> header file. */ /* Define to 1 if you have the <ieeefp.h> header file. */
#undef HAVE_IEEEFP_H #undef HAVE_IEEEFP_H
/* Define to 1 if you have the 'if_nameindex' function. */ /* Define to 1 if you have the `if_nameindex' function. */
#undef HAVE_IF_NAMEINDEX #undef HAVE_IF_NAMEINDEX
/* Define if you have the 'inet_aton' function. */ /* Define if you have the 'inet_aton' function. */
@ -1413,9 +1413,6 @@
#endif #endif
/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
#undef WANT_SIGFPE_HANDLER
/* Define if WINDOW in curses.h offers a field _flags. */ /* Define if WINDOW in curses.h offers a field _flags. */
#undef WINDOW_HAS_FLAGS #undef WINDOW_HAS_FLAGS