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:
parent
502d551c6d
commit
735ae8d139
|
@ -154,10 +154,7 @@ The following exceptions are the exceptions that are usually raised.
|
|||
|
||||
.. exception:: FloatingPointError
|
||||
|
||||
Raised when a floating point operation fails. This exception is always defined,
|
||||
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.
|
||||
Not currently used.
|
||||
|
||||
|
||||
.. exception:: GeneratorExit
|
||||
|
|
|
@ -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`.
|
||||
|
|
@ -24,4 +24,3 @@ overview:
|
|||
gc.rst
|
||||
inspect.rst
|
||||
site.rst
|
||||
fpectl.rst
|
||||
|
|
|
@ -349,48 +349,6 @@ Project, http://www.wide.ad.jp/. ::
|
|||
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
|
||||
----------------------------
|
||||
|
||||
|
|
170
Include/pyfpe.h
170
Include/pyfpe.h
|
@ -1,176 +1,12 @@
|
|||
#ifndef Py_PYFPE_H
|
||||
#define Py_PYFPE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
---------------------------------------------------------------------
|
||||
/ 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.
|
||||
*
|
||||
/* These macros used to do something when Python was built with --with-fpectl,
|
||||
* but support for that was dropped in 3.7. We continue to define them though,
|
||||
* to avoid breaking API users.
|
||||
*/
|
||||
|
||||
#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_END_PROTECT(v)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_PYFPE_H */
|
||||
|
|
|
@ -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.
|
|
@ -334,20 +334,6 @@ _symtable symtablemodule.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.
|
||||
# This require zlib 1.1.3 (or later).
|
||||
# See http://www.gzip.org/zlib/
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -1,20 +1,12 @@
|
|||
#include "pyconfig.h"
|
||||
#include "pyfpe.h"
|
||||
/*
|
||||
* 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.
|
||||
/* These variables used to be used when Python was built with --with-fpectl,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef WANT_SIGFPE_HANDLER
|
||||
jmp_buf PyFPE_jbuf;
|
||||
int PyFPE_counter = 0;
|
||||
#endif
|
||||
#include "setjmp.h"
|
||||
|
||||
/* Have this outside the above #ifdef, since some picky ANSI compilers issue a
|
||||
warning when compiling an empty file. */
|
||||
jmp_buf PyFPE_jbuf;
|
||||
int PyFPE_counter;
|
||||
|
||||
double
|
||||
PyFPE_dummy(void *dummy)
|
||||
|
|
|
@ -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
|
||||
# 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($@)])])
|
||||
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 Copyright © 2004 Scott James Remnant <scott@netsplit.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 of the macros you require.
|
||||
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_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
||||
])dnl PKG_PREREQ
|
||||
|
@ -170,7 +170,7 @@ if test $pkg_failed = yes; then
|
|||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
|
|
|
@ -832,7 +832,6 @@ with_c_locale_coercion
|
|||
with_c_locale_warning
|
||||
with_valgrind
|
||||
with_dtrace
|
||||
with_fpectl
|
||||
with_libm
|
||||
with_libc
|
||||
enable_big_digits
|
||||
|
@ -1539,7 +1538,6 @@ Optional Packages:
|
|||
locale
|
||||
--with-valgrind Enable Valgrind support
|
||||
--with(out)-dtrace disable/enable DTrace support
|
||||
--with-fpectl enable SIGFPE catching
|
||||
--with-libm=STRING math library
|
||||
--with-libc=STRING C library
|
||||
--with(out)-computed-gotos
|
||||
|
@ -13691,29 +13689,6 @@ 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=...
|
||||
|
||||
case $ac_sys_system in
|
||||
|
|
14
configure.ac
14
configure.ac
|
@ -4135,20 +4135,6 @@ AC_CHECK_FUNC(__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=...
|
||||
AC_SUBST(LIBM)
|
||||
case $ac_sys_system in
|
||||
|
|
|
@ -500,7 +500,7 @@
|
|||
/* Define to 1 if you have the <ieeefp.h> header file. */
|
||||
#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
|
||||
|
||||
/* Define if you have the 'inet_aton' function. */
|
||||
|
@ -1413,9 +1413,6 @@
|
|||
#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. */
|
||||
#undef WINDOW_HAS_FLAGS
|
||||
|
||||
|
|
Loading…
Reference in New Issue