FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Changes for Lee Busby's SIGFPE patch set. · python/cpython@52fa3a6 · GitHub

Repository navigation

Commit 52fa3a6

Browse files
committed
Changes for Lee Busby's SIGFPE patch set.
Two new modules fpectl and fpetest. Surround various and sundry f.p. operations with PyFPE_*_PROTECT macros.
1 parent 0ae748d commit 52fa3a6

8 files changed

Lines changed: 492 additions & 1 deletion

File tree

‎Modules/_tkinter.c‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,10 +724,14 @@ Tkapp_ExprDouble (self, args)
724724
{
725725
char *s;
726726
double v;
727+
int retval;
727728

728729
if (!PyArg_Parse(args, "s", &s))
729730
return NULL;
730-
if (Tcl_ExprDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
731+
PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
732+
retval = Tcl_ExprDouble (Tkapp_Interp (self), s, &v);
733+
PyFPE_END_PROTECT
734+
if (retval == TCL_ERROR)
731735
return Tkinter_Error(self);
732736
return Py_BuildValue("d", v);
733737
}

‎Modules/cmathmodule.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ math_1(args, func)
247247
if (!PyArg_ParseTuple(args, "D", &x))
248248
return NULL;
249249
errno = 0;
250+
PyFPE_START_PROTECT("complex function", return 0)
250251
x = (*func)(x);
252+
PyFPE_END_PROTECT
251253
CHECK(x.real);
252254
CHECK(x.imag);
253255
if (errno != 0)

‎Modules/fpectlmodule.c‎

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
/*
2+
---------------------------------------------------------------------
3+
/ Copyright (c) 1996. \
4+
| The Regents of the University of California. |
5+
| All rights reserved. |
6+
| |
7+
| Permission to use, copy, modify, and distribute this software for |
8+
| any purpose without fee is hereby granted, provided that this en- |
9+
| tire notice is included in all copies of any software which is or |
10+
| includes a copy or modification of this software and in all |
11+
| copies of the supporting documentation for such software. |
12+
| |
13+
| This work was produced at the University of California, Lawrence |
14+
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
15+
| between the U.S. Department of Energy and The Regents of the |
16+
| University of California for the operation of UC LLNL. |
17+
| |
18+
| DISCLAIMER |
19+
| |
20+
| This software was prepared as an account of work sponsored by an |
21+
| agency of the United States Government. Neither the United States |
22+
| Government nor the University of California nor any of their em- |
23+
| ployees, makes any warranty, express or implied, or assumes any |
24+
| liability or responsibility for the accuracy, completeness, or |
25+
| usefulness of any information, apparatus, product, or process |
26+
| disclosed, or represents that its use would not infringe |
27+
| privately-owned rights. Reference herein to any specific commer- |
28+
| cial products, process, or service by trade name, trademark, |
29+
| manufacturer, or otherwise, does not necessarily constitute or |
30+
| imply its endorsement, recommendation, or favoring by the United |
31+
| States Government or the University of California. The views and |
32+
| opinions of authors expressed herein do not necessarily state or |
33+
| reflect those of the United States Government or the University |
34+
| of California, and shall not be used for advertising or product |
35+
\ endorsement purposes. /
36+
---------------------------------------------------------------------
37+
*/
38+
39+
/*
40+
Floating point exception control module.
41+
42+
This Python module provides bare-bones control over floating point
43+
units from several hardware manufacturers. Specifically, it allows
44+
the user to turn on the generation of SIGFPE whenever any of the
45+
three serious IEEE 754 exceptions (Division by Zero, Overflow,
46+
Invalid Operation) occurs. We currently ignore Underflow and
47+
Inexact Result exceptions, although those could certainly be added
48+
if desired.
49+
50+
The module also establishes a signal handler for SIGFPE during
51+
initialization. This builds on code found in the Python
52+
distribution at Include/pyfpe.h and Python/pyfpe.c. If those files
53+
are not in your Python distribution, find them in a patch at
54+
ftp://icf.llnl.gov/pub/python/busby/patches.961108.tgz.
55+
56+
This module is only useful to you if it happens to include code
57+
specific for your hardware and software environment. If you can
58+
contribute OS-specific code for new platforms, or corrections for
59+
the code provided, it will be greatly appreciated.
60+
61+
** Version 1.0: September 20, 1996. Lee Busby, LLNL.
62+
*/
63+
64+
#ifdef __cplusplus
65+
extern "C" {
66+
#endif
67+
68+
#include "Python.h"
69+
#include <signal.h>
70+
71+
#ifndef WANT_SIGFPE_HANDLER
72+
/* Define locally if they are not defined in Python. This gives only
73+
* the limited control to induce a core dump in case of an exception.
74+
*/
75+
static jmp_buf PyFPE_jbuf;
76+
static int PyFPE_counter = 0;
77+
#endif
78+
79+
typedef RETSIGTYPE Sigfunc(int);
80+
static Sigfunc sigfpe_handler;
81+
static void fpe_reset(Sigfunc *);
82+
83+
static PyObject *fpe_error;
84+
void initfpectl(void);
85+
static PyObject *turnon_sigfpe (PyObject *self,PyObject *args);
86+
static PyObject *turnoff_sigfpe (PyObject *self,PyObject *args);
87+
88+
static PyMethodDef fpectl_methods[] = {
89+
{"turnon_sigfpe", (PyCFunction) turnon_sigfpe, 1},
90+
{"turnoff_sigfpe", (PyCFunction) turnoff_sigfpe, 1},
91+
{0,0}
92+
};
93+
94+
static PyObject *turnon_sigfpe(PyObject *self,PyObject *args)
95+
{
96+
/* Do any architecture-specific one-time only initialization here. */
97+
98+
fpe_reset(sigfpe_handler);
99+
Py_INCREF (Py_None);
100+
return Py_None;
101+
}
102+
103+
static void fpe_reset(Sigfunc *handler)
104+
{
105+
/* Reset the exception handling machinery, and reset the signal
106+
* handler for SIGFPE to the given handler.
107+
*/
108+
109+
/*-- IRIX -----------------------------------------------------------------*/
110+
#if defined(sgi)
111+
/* See man page on handle_sigfpes -- must link with -lfpe
112+
* My usage doesn't follow the man page exactly. Maybe somebody
113+
* else can explain handle_sigfpes to me....
114+
* cc -c -I/usr/local/python/include fpectlmodule.c
115+
* ld -shared -o fpectlmodule.so fpectlmodule.o -lfpe
116+
*/
117+
#include <sigfpe.h>
118+
typedef void user_routine (unsigned[5], int[2]);
119+
typedef void abort_routine (unsigned long);
120+
handle_sigfpes(_OFF, 0,
121+
(user_routine *)0,
122+
_TURN_OFF_HANDLER_ON_ERROR,
123+
(abort_routine*)0);
124+
handle_sigfpes(_ON, _EN_OVERFL | _EN_DIVZERO | _EN_INVALID,
125+
(user_routine *)0,
126+
_ABORT_ON_ERROR,
127+
(abort_routine*)0);
128+
signal(SIGFPE, handler);
129+
130+
/*-- SunOS and Solaris ----------------------------------------------------*/
131+
#elif defined(sun)
132+
/* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags
133+
man pages (SunOS or Solaris)
134+
cc -c -I/usr/local/python/include fpectlmodule.c
135+
ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm
136+
*/
137+
#include <math.h>
138+
char *mode="exception", *in="all", *out;
139+
(void) nonstandard_arithmetic();
140+
(void) ieee_flags("clearall",mode,in,&out);
141+
(void) ieee_handler("set","common",(sigfpe_handler_type)handler);
142+
signal(SIGFPE, handler);
143+
144+
/*-- HPUX -----------------------------------------------------------------*/
145+
#elif defined(__hppa) || defined(hppa)
146+
/* References: fpsetmask man page */
147+
/* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */
148+
/* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */
149+
#include <math.h>
150+
fpsetdefaults();
151+
signal(SIGFPE, handler);
152+
153+
/*-- IBM AIX --------------------------------------------------------------*/
154+
#elif defined(__AIX) || defined(_AIX)
155+
/* References: fp_trap, fp_enable man pages */
156+
#include <fptrap.h>
157+
fp_trap(FP_TRAP_SYNC);
158+
fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
159+
signal(SIGFPE, handler);
160+
161+
/*-- DEC ALPHA OSF --------------------------------------------------------*/
162+
#elif defined(__alpha)
163+
/* References: exception_intro, ieee man pages */
164+
/* cc -c -I/usr/local/python/include fpectlmodule.c */
165+
/* ld -shared -o fpectlmodule.so fpectlmodule.o */
166+
#include <machine/fpu.h>
167+
unsigned long fp_control =
168+
IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
169+
ieee_set_fp_control(fp_control);
170+
signal(SIGFPE, handler);
171+
172+
/*-- Cray Unicos ----------------------------------------------------------*/
173+
#elif defined(cray)
174+
/* UNICOS delivers SIGFPE by default, but no matherr */
175+
#ifdef HAS_LIBMSET
176+
libmset(-1);
177+
#endif
178+
signal(SIGFPE, handler);
179+
180+
/*-- Linux ----------------------------------------------------------------*/
181+
#elif defined(linux)
182+
/* Linux delivers SIGFPE by default,
183+
except for log(0), atanh(-1), 0.^0.
184+
*/
185+
signal(SIGFPE, handler);
186+
187+
/*-- NeXT -----------------------------------------------------------------*/
188+
#elif defined(NeXT) && defined(m68k) && defined(__GNUC__)
189+
/* NeXT needs explicit csr set to generate SIGFPE */
190+
asm("fmovel #0x1400,fpcr"); /* set OVFL and ZD bits */
191+
signal(SIGFPE, handler);
192+
193+
/*-- Microsoft Windows, NT ------------------------------------------------*/
194+
#elif defined(_MSC_VER)
195+
/* Reference: Visual C++ Books Online 4.2,
196+
Run-Time Library Reference, _control87, _controlfp */
197+
#include <float.h>
198+
unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW;
199+
(void)_controlfp(0, cw);
200+
signal(SIGFPE, handler);
201+
202+
/*-- Give Up --------------------------------------------------------------*/
203+
#else
204+
fputs("Operation not implemented\n", stderr);
205+
#endif
206+
207+
}
208+
209+
static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
210+
{
211+
fputs("Operation not implemented\n", stderr);
212+
Py_INCREF (Py_None);
213+
return Py_None;
214+
}
215+
216+
static void sigfpe_handler(int signo)
217+
{
218+
fpe_reset(sigfpe_handler);
219+
if(PyFPE_counter) {
220+
longjmp(PyFPE_jbuf, 1);
221+
} else {
222+
Py_FatalError("Unprotected floating point exception");
223+
}
224+
}
225+
226+
void initfpectl(void)
227+
{
228+
PyObject *m, *d;
229+
static int already_initialized = 0;
230+
231+
if (already_initialized) return;
232+
m = Py_InitModule("fpectl", fpectl_methods);
233+
d = PyModule_GetDict(m);
234+
fpe_error = PyString_FromString("fpectl.error");
235+
PyDict_SetItemString(d, "error", fpe_error);
236+
237+
if (PyErr_Occurred())
238+
Py_FatalError("Cannot initialize module fpectl");
239+
already_initialized = 1;
240+
}
241+
242+
#ifdef __cplusplus
243+
}
244+
#endif

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL