blob: 39b70bcf3a10b4a9349d784d719e2fd53e24e0c7 [file] [log] [blame]
Victor Stinner024e37a2011-03-31 01:31:06 +02001#include "Python.h"
2#include "pythread.h"
3#include <signal.h>
4#include <object.h>
5#include <frameobject.h>
6#include <signal.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +02007#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinner7a399122014-09-30 13:40:12 +02008# include <pthread.h>
9#endif
10#ifdef MS_WINDOWS
11# include <windows.h>
12#endif
13#ifdef HAVE_SYS_RESOURCE_H
14# include <sys/resource.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +020015#endif
16
Victor Stinner96994402011-04-07 11:37:19 +020017/* Allocate at maximum 100 MB of the stack to raise the stack overflow */
18#define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
19
Victor Stinner024e37a2011-03-31 01:31:06 +020020#ifdef WITH_THREAD
21# define FAULTHANDLER_LATER
22#endif
23
24#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020025 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
26 SIGILL can be handled by the process, and these signals can only be used
27 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020028# define FAULTHANDLER_USER
29#endif
30
Victor Stinnerc7489a52015-04-01 18:48:58 +020031#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
Victor Stinner024e37a2011-03-31 01:31:06 +020032
Victor Stinnerbd303c12013-11-07 23:07:29 +010033_Py_IDENTIFIER(enable);
34_Py_IDENTIFIER(fileno);
35_Py_IDENTIFIER(flush);
36_Py_IDENTIFIER(stderr);
37
Victor Stinner024e37a2011-03-31 01:31:06 +020038#ifdef HAVE_SIGACTION
39typedef struct sigaction _Py_sighandler_t;
40#else
41typedef PyOS_sighandler_t _Py_sighandler_t;
42#endif
43
44typedef struct {
45 int signum;
46 int enabled;
47 const char* name;
48 _Py_sighandler_t previous;
49 int all_threads;
50} fault_handler_t;
51
52static struct {
53 int enabled;
54 PyObject *file;
55 int fd;
56 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020057 PyInterpreterState *interp;
Victor Stinner46c2b812017-04-21 18:06:13 +020058#ifdef MS_WINDOWS
59 void *exc_handler;
60#endif
Victor Stinner024e37a2011-03-31 01:31:06 +020061} fatal_error = {0, NULL, -1, 0};
62
63#ifdef FAULTHANDLER_LATER
64static struct {
65 PyObject *file;
66 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020067 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020068 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020069 PyInterpreterState *interp;
70 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020071 char *header;
72 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020073 /* The main thread always holds this lock. It is only released when
74 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020075 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020076 PyThread_type_lock cancel_event;
77 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020078 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020079} thread;
80#endif
81
82#ifdef FAULTHANDLER_USER
83typedef struct {
84 int enabled;
85 PyObject *file;
86 int fd;
87 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020088 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020089 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020090 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020091} user_signal_t;
92
93static user_signal_t *user_signals;
94
95/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +020096#ifndef NSIG
97# if defined(_NSIG)
98# define NSIG _NSIG /* For BSD/SysV */
99# elif defined(_SIGMAX)
100# define NSIG (_SIGMAX + 1) /* For QNX */
101# elif defined(SIGMAX)
102# define NSIG (SIGMAX + 1) /* For djgpp */
103# else
104# define NSIG 64 /* Use a reasonable default value */
105# endif
106#endif
107
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200108static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200109#endif /* FAULTHANDLER_USER */
110
111
112static fault_handler_t faulthandler_handlers[] = {
113#ifdef SIGBUS
114 {SIGBUS, 0, "Bus error", },
115#endif
116#ifdef SIGILL
117 {SIGILL, 0, "Illegal instruction", },
118#endif
119 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200120 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200121 /* define SIGSEGV at the end to make it the default choice if searching the
122 handler fails in faulthandler_fatal_error() */
123 {SIGSEGV, 0, "Segmentation fault", }
124};
Victor Stinner404cdc52016-03-23 10:39:17 +0100125static const size_t faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200126 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200127
128#ifdef HAVE_SIGALTSTACK
129static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700130static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200131#endif
132
133
134/* Get the file descriptor of a file by calling its fileno() method and then
135 call its flush() method.
136
137 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100138 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200139
Victor Stinner95bb7142015-03-12 15:32:03 +0100140 On success, return the file descriptor and write the new file into *file_ptr.
141 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200142
Victor Stinner95bb7142015-03-12 15:32:03 +0100143static int
144faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200145{
146 PyObject *result;
147 long fd_long;
148 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100149 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200150
151 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100152 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200153 if (file == NULL) {
154 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100155 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200156 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200157 if (file == Py_None) {
158 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100159 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200160 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200161 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100162 else if (PyLong_Check(file)) {
163 fd = _PyLong_AsInt(file);
164 if (fd == -1 && PyErr_Occurred())
165 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700166 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100167 PyErr_SetString(PyExc_ValueError,
168 "file is not a valid file descripter");
169 return -1;
170 }
171 *file_ptr = NULL;
172 return fd;
173 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200174
Victor Stinner3466bde2016-09-05 18:16:01 -0700175 result = _PyObject_CallMethodId(file, &PyId_fileno, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200176 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100177 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200178
179 fd = -1;
180 if (PyLong_Check(result)) {
181 fd_long = PyLong_AsLong(result);
182 if (0 <= fd_long && fd_long < INT_MAX)
183 fd = (int)fd_long;
184 }
185 Py_DECREF(result);
186
187 if (fd == -1) {
188 PyErr_SetString(PyExc_RuntimeError,
189 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100190 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200191 }
192
Victor Stinner3466bde2016-09-05 18:16:01 -0700193 result = _PyObject_CallMethodId(file, &PyId_flush, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200194 if (result != NULL)
195 Py_DECREF(result);
196 else {
197 /* ignore flush() error */
198 PyErr_Clear();
199 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100200 *file_ptr = file;
201 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200202}
203
Victor Stinnera4de6d82011-04-09 00:47:23 +0200204/* Get the state of the current thread: only call this function if the current
205 thread holds the GIL. Raise an exception on error. */
206static PyThreadState*
207get_thread_state(void)
208{
Victor Stinner861d9ab2016-03-16 22:45:24 +0100209 PyThreadState *tstate = _PyThreadState_UncheckedGet();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200210 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100211 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200212 PyErr_SetString(PyExc_RuntimeError,
213 "unable to get the current thread state");
214 return NULL;
215 }
216 return tstate;
217}
218
Victor Stinnerc7489a52015-04-01 18:48:58 +0200219static void
220faulthandler_dump_traceback(int fd, int all_threads,
221 PyInterpreterState *interp)
222{
223 static volatile int reentrant = 0;
224 PyThreadState *tstate;
225
226 if (reentrant)
227 return;
228
229 reentrant = 1;
230
231#ifdef WITH_THREAD
232 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
233 are thus delivered to the thread that caused the fault. Get the Python
234 thread state of the current thread.
235
236 PyThreadState_Get() doesn't give the state of the thread that caused the
237 fault if the thread released the GIL, and so this function cannot be
238 used. Read the thread local storage (TLS) instead: call
239 PyGILState_GetThisThreadState(). */
240 tstate = PyGILState_GetThisThreadState();
241#else
Victor Stinner861d9ab2016-03-16 22:45:24 +0100242 tstate = _PyThreadState_UncheckedGet();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200243#endif
244
Victor Stinner861d9ab2016-03-16 22:45:24 +0100245 if (all_threads) {
246 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
247 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200248 else {
249 if (tstate != NULL)
250 _Py_DumpTraceback(fd, tstate);
251 }
252
253 reentrant = 0;
254}
255
Victor Stinner024e37a2011-03-31 01:31:06 +0200256static PyObject*
257faulthandler_dump_traceback_py(PyObject *self,
258 PyObject *args, PyObject *kwargs)
259{
260 static char *kwlist[] = {"file", "all_threads", NULL};
261 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200262 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200263 PyThreadState *tstate;
264 const char *errmsg;
265 int fd;
266
267 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
268 "|Oi:dump_traceback", kwlist,
269 &file, &all_threads))
270 return NULL;
271
Victor Stinner95bb7142015-03-12 15:32:03 +0100272 fd = faulthandler_get_fileno(&file);
273 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200274 return NULL;
275
Victor Stinnera4de6d82011-04-09 00:47:23 +0200276 tstate = get_thread_state();
277 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200278 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200279
280 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100281 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200282 if (errmsg != NULL) {
283 PyErr_SetString(PyExc_RuntimeError, errmsg);
284 return NULL;
285 }
286 }
287 else {
288 _Py_DumpTraceback(fd, tstate);
289 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200290
291 if (PyErr_CheckSignals())
292 return NULL;
293
Victor Stinner024e37a2011-03-31 01:31:06 +0200294 Py_RETURN_NONE;
295}
296
Victor Stinner404cdc52016-03-23 10:39:17 +0100297static void
298faulthandler_disable_fatal_handler(fault_handler_t *handler)
299{
300 if (!handler->enabled)
301 return;
302 handler->enabled = 0;
303#ifdef HAVE_SIGACTION
304 (void)sigaction(handler->signum, &handler->previous, NULL);
305#else
306 (void)signal(handler->signum, handler->previous);
307#endif
308}
309
Victor Stinner024e37a2011-03-31 01:31:06 +0200310
Victor Stinner410dd7d2011-05-11 20:56:08 +0200311/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200312
313 Display the current Python traceback, restore the previous handler and call
314 the previous handler.
315
Victor Stinner410dd7d2011-05-11 20:56:08 +0200316 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200317 signal handler would not be called (for an unknown reason). The execution of
318 the program continues at faulthandler_fatal_error() exit, but the same
319 instruction will raise the same fault (signal), and so the previous handler
320 will be called.
321
Victor Stinner410dd7d2011-05-11 20:56:08 +0200322 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200323
324static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200325faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200326{
327 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100328 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200329 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200330 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200331
332 if (!fatal_error.enabled)
333 return;
334
335 for (i=0; i < faulthandler_nsignals; i++) {
336 handler = &faulthandler_handlers[i];
337 if (handler->signum == signum)
338 break;
339 }
340 if (handler == NULL) {
341 /* faulthandler_nsignals == 0 (unlikely) */
342 return;
343 }
344
345 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100346 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200347
348 PUTS(fd, "Fatal Python error: ");
349 PUTS(fd, handler->name);
350 PUTS(fd, "\n\n");
351
Victor Stinnerc7489a52015-04-01 18:48:58 +0200352 faulthandler_dump_traceback(fd, fatal_error.all_threads,
353 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200354
Victor Stinnerc9256172011-05-07 12:20:11 +0200355 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200356#ifdef MS_WINDOWS
357 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200358 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200359 handler, because the Windows signal handler would not be called */
360 return;
361 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200362#endif
R David Murrayfc069992013-12-13 20:52:19 -0500363 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200364 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
365 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200366}
367
Victor Stinner404cdc52016-03-23 10:39:17 +0100368#ifdef MS_WINDOWS
369static LONG WINAPI
370faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
371{
372 const int fd = fatal_error.fd;
373 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100374 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100375
Steve Dowere6a23c82017-06-05 15:54:15 -0700376 /* bpo-30557: only log fatal exceptions */
377 if (!(code & 0x80000000)) {
Victor Stinner412a5e72016-03-23 14:44:14 +0100378 /* call the next exception handler */
379 return EXCEPTION_CONTINUE_SEARCH;
380 }
381
382 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100383 switch (code)
384 {
385 /* only format most common errors */
386 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
387 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
388 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
389 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
390 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
391 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
392 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
393 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700394 PUTS(fd, "code 0x");
395 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100396 }
397 PUTS(fd, "\n\n");
398
399 if (code == EXCEPTION_ACCESS_VIOLATION) {
400 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200401 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100402 fault_handler_t *handler = &faulthandler_handlers[i];
403 if (handler->signum == SIGSEGV) {
404 faulthandler_disable_fatal_handler(handler);
405 break;
406 }
407 }
408 }
409
410 faulthandler_dump_traceback(fd, fatal_error.all_threads,
411 fatal_error.interp);
412
413 /* call the next exception handler */
414 return EXCEPTION_CONTINUE_SEARCH;
415}
416#endif
417
Victor Stinnerd727e232011-04-01 12:13:55 +0200418/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200419
doko@ubuntu.combc731502016-05-18 01:06:01 +0200420static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100421faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200422{
Victor Stinner404cdc52016-03-23 10:39:17 +0100423 if (fatal_error.enabled) {
424 return 0;
425 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100426 fatal_error.enabled = 1;
427
Victor Stinner46c2b812017-04-21 18:06:13 +0200428 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100429 fault_handler_t *handler;
430#ifdef HAVE_SIGACTION
431 struct sigaction action;
432#endif
433 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100434
Victor Stinner928ad282016-03-23 15:19:12 +0100435 handler = &faulthandler_handlers[i];
436 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100437#ifdef HAVE_SIGACTION
438 action.sa_handler = faulthandler_fatal_error;
439 sigemptyset(&action.sa_mask);
440 /* Do not prevent the signal from being received from within
441 its own signal handler */
442 action.sa_flags = SA_NODEFER;
443#ifdef HAVE_SIGALTSTACK
444 if (stack.ss_sp != NULL) {
445 /* Call the signal handler on an alternate signal stack
446 provided by sigaltstack() */
447 action.sa_flags |= SA_ONSTACK;
448 }
449#endif
450 err = sigaction(handler->signum, &action, &handler->previous);
451#else
452 handler->previous = signal(handler->signum,
453 faulthandler_fatal_error);
454 err = (handler->previous == SIG_ERR);
455#endif
456 if (err) {
457 PyErr_SetFromErrno(PyExc_RuntimeError);
458 return -1;
459 }
460
461 handler->enabled = 1;
462 }
463
464#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200465 assert(fatal_error.exc_handler == NULL);
466 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100467#endif
468 return 0;
469}
470
471static PyObject*
472faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
473{
474 static char *kwlist[] = {"file", "all_threads", NULL};
475 PyObject *file = NULL;
476 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200477 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200478 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200479
480 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
481 "|Oi:enable", kwlist, &file, &all_threads))
482 return NULL;
483
Victor Stinner95bb7142015-03-12 15:32:03 +0100484 fd = faulthandler_get_fileno(&file);
485 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200486 return NULL;
487
Victor Stinnera4de6d82011-04-09 00:47:23 +0200488 tstate = get_thread_state();
489 if (tstate == NULL)
490 return NULL;
491
Victor Stinner95bb7142015-03-12 15:32:03 +0100492 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300493 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200494 fatal_error.fd = fd;
495 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200496 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200497
Victor Stinner404cdc52016-03-23 10:39:17 +0100498 if (faulthandler_enable() < 0) {
499 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200500 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100501
Victor Stinner024e37a2011-03-31 01:31:06 +0200502 Py_RETURN_NONE;
503}
504
505static void
506faulthandler_disable(void)
507{
Victor Stinner024e37a2011-03-31 01:31:06 +0200508 if (fatal_error.enabled) {
509 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200510 for (size_t i=0; i < faulthandler_nsignals; i++) {
511 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200512 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100513 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200514 }
515 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200516#ifdef MS_WINDOWS
517 if (fatal_error.exc_handler != NULL) {
518 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
519 fatal_error.exc_handler = NULL;
520 }
521#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200522 Py_CLEAR(fatal_error.file);
523}
524
525static PyObject*
526faulthandler_disable_py(PyObject *self)
527{
528 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200529 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200530 }
531 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200532 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200533}
534
535static PyObject*
536faulthandler_is_enabled(PyObject *self)
537{
538 return PyBool_FromLong(fatal_error.enabled);
539}
540
541#ifdef FAULTHANDLER_LATER
542
543static void
544faulthandler_thread(void *unused)
545{
546 PyLockStatus st;
547 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200548 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200549#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200550 sigset_t set;
551
552 /* we don't want to receive any signal */
553 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200554 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200555#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200556
557 do {
558 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200559 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200560 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200561 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200562 break;
563 }
564 /* Timeout => dump traceback */
565 assert(st == PY_LOCK_FAILURE);
566
Victor Stinnerc7489a52015-04-01 18:48:58 +0200567 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200568
Victor Stinner861d9ab2016-03-16 22:45:24 +0100569 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200570 ok = (errmsg == NULL);
571
572 if (thread.exit)
573 _exit(1);
574 } while (ok && thread.repeat);
575
576 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200577 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200578}
579
580static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200581cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200582{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200583 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200584 PyThread_release_lock(thread.cancel_event);
585
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200586 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200587 PyThread_acquire_lock(thread.running, 1);
588 PyThread_release_lock(thread.running);
589
590 /* The main thread should always hold the cancel_event lock */
591 PyThread_acquire_lock(thread.cancel_event, 1);
592
Victor Stinner024e37a2011-03-31 01:31:06 +0200593 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200594 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200595 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200596 thread.header = NULL;
597 }
598}
599
600static char*
601format_timeout(double timeout)
602{
603 unsigned long us, sec, min, hour;
604 double intpart, fracpart;
605 char buffer[100];
606
607 fracpart = modf(timeout, &intpart);
608 sec = (unsigned long)intpart;
609 us = (unsigned long)(fracpart * 1e6);
610 min = sec / 60;
611 sec %= 60;
612 hour = min / 60;
613 min %= 60;
614
615 if (us != 0)
616 PyOS_snprintf(buffer, sizeof(buffer),
617 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
618 hour, min, sec, us);
619 else
620 PyOS_snprintf(buffer, sizeof(buffer),
621 "Timeout (%lu:%02lu:%02lu)!\n",
622 hour, min, sec);
623
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200624 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200625}
626
627static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200628faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200629 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200630{
631 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
632 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200633 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200634 int repeat = 0;
635 PyObject *file = NULL;
636 int fd;
637 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200638 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200639 char *header;
640 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200641
642 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Georg Brandldeb92b52012-09-22 08:58:55 +0200643 "d|iOi:dump_traceback_later", kwlist,
Victor Stinner024e37a2011-03-31 01:31:06 +0200644 &timeout, &repeat, &file, &exit))
645 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200646 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200647 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
648 return NULL;
649 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200650 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200651 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200652 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
653 return NULL;
654 }
655
Victor Stinnera4de6d82011-04-09 00:47:23 +0200656 tstate = get_thread_state();
657 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200658 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200659
Victor Stinner95bb7142015-03-12 15:32:03 +0100660 fd = faulthandler_get_fileno(&file);
661 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200662 return NULL;
663
Victor Stinnerc790a532011-04-08 13:39:59 +0200664 /* format the timeout */
665 header = format_timeout(timeout);
666 if (header == NULL)
667 return PyErr_NoMemory();
668 header_len = strlen(header);
669
Victor Stinner024e37a2011-03-31 01:31:06 +0200670 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200671 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200672
Victor Stinner95bb7142015-03-12 15:32:03 +0100673 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300674 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200675 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200676 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200677 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200678 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200679 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200680 thread.header = header;
681 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200682
683 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200684 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200685
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200686 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200687 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200688 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200689 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200690 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200691 PyErr_SetString(PyExc_RuntimeError,
692 "unable to start watchdog thread");
693 return NULL;
694 }
695
696 Py_RETURN_NONE;
697}
698
699static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200700faulthandler_cancel_dump_traceback_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200701{
Georg Brandldeb92b52012-09-22 08:58:55 +0200702 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200703 Py_RETURN_NONE;
704}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200705#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200706
707#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200708static int
709faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
710{
711#ifdef HAVE_SIGACTION
712 struct sigaction action;
713 action.sa_handler = faulthandler_user;
714 sigemptyset(&action.sa_mask);
715 /* if the signal is received while the kernel is executing a system
716 call, try to restart the system call instead of interrupting it and
717 return EINTR. */
718 action.sa_flags = SA_RESTART;
719 if (chain) {
720 /* do not prevent the signal from being received from within its
721 own signal handler */
722 action.sa_flags = SA_NODEFER;
723 }
724#ifdef HAVE_SIGALTSTACK
725 if (stack.ss_sp != NULL) {
726 /* Call the signal handler on an alternate signal stack
727 provided by sigaltstack() */
728 action.sa_flags |= SA_ONSTACK;
729 }
730#endif
731 return sigaction(signum, &action, p_previous);
732#else
733 _Py_sighandler_t previous;
734 previous = signal(signum, faulthandler_user);
735 if (p_previous != NULL)
736 *p_previous = previous;
737 return (previous == SIG_ERR);
738#endif
739}
740
Victor Stinner024e37a2011-03-31 01:31:06 +0200741/* Handler of user signals (e.g. SIGUSR1).
742
743 Dump the traceback of the current thread, or of all threads if
744 thread.all_threads is true.
745
746 This function is signal safe and should only call signal safe functions. */
747
748static void
749faulthandler_user(int signum)
750{
751 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200752 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200753
754 user = &user_signals[signum];
755 if (!user->enabled)
756 return;
757
Victor Stinnerc7489a52015-04-01 18:48:58 +0200758 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200759
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200760#ifdef HAVE_SIGACTION
761 if (user->chain) {
762 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200763 errno = save_errno;
764
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200765 /* call the previous signal handler */
766 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200767
768 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200769 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200770 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200771 }
772#else
773 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200774 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200775 /* call the previous signal handler */
776 user->previous(signum);
777 }
778#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200779}
780
781static int
782check_signum(int signum)
783{
Victor Stinner46c2b812017-04-21 18:06:13 +0200784 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200785 if (faulthandler_handlers[i].signum == signum) {
786 PyErr_Format(PyExc_RuntimeError,
787 "signal %i cannot be registered, "
788 "use enable() instead",
789 signum);
790 return 0;
791 }
792 }
793 if (signum < 1 || NSIG <= signum) {
794 PyErr_SetString(PyExc_ValueError, "signal number out of range");
795 return 0;
796 }
797 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200798}
799
800static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200801faulthandler_register_py(PyObject *self,
802 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200803{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200804 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200805 int signum;
806 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200807 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200808 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200809 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200810 user_signal_t *user;
811 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200812 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200813 int err;
814
815 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200816 "i|Oii:register", kwlist,
817 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200818 return NULL;
819
Victor Stinner44378d42011-04-01 15:37:12 +0200820 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200821 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200822
Victor Stinnera4de6d82011-04-09 00:47:23 +0200823 tstate = get_thread_state();
824 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200825 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200826
Victor Stinner95bb7142015-03-12 15:32:03 +0100827 fd = faulthandler_get_fileno(&file);
828 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200829 return NULL;
830
831 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200832 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200833 if (user_signals == NULL)
834 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200835 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200836 }
837 user = &user_signals[signum];
838
839 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200840 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200841 if (err) {
842 PyErr_SetFromErrno(PyExc_OSError);
843 return NULL;
844 }
Victor Stinner8d379542013-07-02 00:14:56 +0200845
846 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200847 }
848
Victor Stinner95bb7142015-03-12 15:32:03 +0100849 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300850 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200851 user->fd = fd;
852 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200853 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200854 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200855 user->enabled = 1;
856
857 Py_RETURN_NONE;
858}
859
860static int
861faulthandler_unregister(user_signal_t *user, int signum)
862{
Victor Stinnera01ca122011-04-01 12:56:17 +0200863 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200864 return 0;
865 user->enabled = 0;
866#ifdef HAVE_SIGACTION
867 (void)sigaction(signum, &user->previous, NULL);
868#else
869 (void)signal(signum, user->previous);
870#endif
871 Py_CLEAR(user->file);
872 user->fd = -1;
873 return 1;
874}
875
876static PyObject*
877faulthandler_unregister_py(PyObject *self, PyObject *args)
878{
879 int signum;
880 user_signal_t *user;
881 int change;
882
883 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
884 return NULL;
885
Victor Stinner44378d42011-04-01 15:37:12 +0200886 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200887 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200888
Victor Stinnercfa71232011-04-08 12:48:15 +0200889 if (user_signals == NULL)
890 Py_RETURN_FALSE;
891
Victor Stinner024e37a2011-03-31 01:31:06 +0200892 user = &user_signals[signum];
893 change = faulthandler_unregister(user, signum);
894 return PyBool_FromLong(change);
895}
896#endif /* FAULTHANDLER_USER */
897
898
Victor Stinner7a399122014-09-30 13:40:12 +0200899static void
900faulthandler_suppress_crash_report(void)
901{
902#ifdef MS_WINDOWS
903 UINT mode;
904
905 /* Configure Windows to not display the Windows Error Reporting dialog */
906 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
907 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
908#endif
909
910#ifdef HAVE_SYS_RESOURCE_H
911 struct rlimit rl;
912
913 /* Disable creation of core dump */
914 if (getrlimit(RLIMIT_CORE, &rl) != 0) {
915 rl.rlim_cur = 0;
916 setrlimit(RLIMIT_CORE, &rl);
917 }
918#endif
919
920#ifdef _MSC_VER
921 /* Visual Studio: configure abort() to not display an error message nor
922 open a popup asking to report the fault. */
923 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
924#endif
925}
926
Victor Stinner024e37a2011-03-31 01:31:06 +0200927static PyObject *
928faulthandler_read_null(PyObject *self, PyObject *args)
929{
Victor Stinnera2477202012-01-30 00:07:43 +0100930 volatile int *x;
931 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +0100932
Victor Stinner7a399122014-09-30 13:40:12 +0200933 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +0100934 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +0200935 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +0200936 return PyLong_FromLong(y);
937
938}
939
Victor Stinner50838282014-09-30 13:54:14 +0200940static void
941faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200942{
Victor Stinner7a399122014-09-30 13:40:12 +0200943 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +0200944#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200945 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
946 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200947 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200948 SIGSEGV was raised by the kernel because of a fault, and so if the
949 program retries to execute the same instruction, the fault will be
950 raised again.
951
952 Here the fault is simulated by a fake SIGSEGV signal raised by the
953 application. We have to raise SIGSEGV at lease twice: once for
954 faulthandler_fatal_error(), and one more time for the previous signal
955 handler. */
956 while(1)
957 raise(SIGSEGV);
958#else
959 raise(SIGSEGV);
960#endif
Victor Stinner50838282014-09-30 13:54:14 +0200961}
962
963static PyObject *
964faulthandler_sigsegv(PyObject *self, PyObject *args)
965{
966 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +0100967 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +0200968 return NULL;
969
970 if (release_gil) {
971 Py_BEGIN_ALLOW_THREADS
972 faulthandler_raise_sigsegv();
973 Py_END_ALLOW_THREADS
974 } else {
975 faulthandler_raise_sigsegv();
976 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200977 Py_RETURN_NONE;
978}
979
Victor Stinner861d9ab2016-03-16 22:45:24 +0100980#ifdef WITH_THREAD
981static void
982faulthandler_fatal_error_thread(void *plock)
983{
Victor Stinner9a2329f2016-12-05 17:56:36 +0100984#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +0100985 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +0100986#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +0100987
988 Py_FatalError("in new thread");
989
Victor Stinner9a2329f2016-12-05 17:56:36 +0100990#ifndef __clang__
991 /* Issue #28152: Py_FatalError() is declared with
992 __attribute__((__noreturn__)). GCC emits a warning without
993 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
994 emits a warning on the return. */
995
Victor Stinner861d9ab2016-03-16 22:45:24 +0100996 /* notify the caller that we are done */
997 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +0100998#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +0100999}
1000
1001static PyObject *
1002faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1003{
1004 long thread;
1005 PyThread_type_lock lock;
1006
1007 faulthandler_suppress_crash_report();
1008
1009 lock = PyThread_allocate_lock();
1010 if (lock == NULL)
1011 return PyErr_NoMemory();
1012
1013 PyThread_acquire_lock(lock, WAIT_LOCK);
1014
1015 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1016 if (thread == -1) {
1017 PyThread_free_lock(lock);
1018 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1019 return NULL;
1020 }
1021
1022 /* wait until the thread completes: it will never occur, since Py_FatalError()
1023 exits the process immedialty. */
1024 PyThread_acquire_lock(lock, WAIT_LOCK);
1025 PyThread_release_lock(lock);
1026 PyThread_free_lock(lock);
1027
1028 Py_RETURN_NONE;
1029}
1030#endif
1031
Victor Stinner024e37a2011-03-31 01:31:06 +02001032static PyObject *
1033faulthandler_sigfpe(PyObject *self, PyObject *args)
1034{
1035 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1036 PowerPC. Use volatile to disable compile-time optimizations. */
1037 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001038 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001039 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001040 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1041 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001042 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001043 /* This line is never reached, but we pretend to make something with z
1044 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001045 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001046}
1047
Victor Stinnerd727e232011-04-01 12:13:55 +02001048static PyObject *
1049faulthandler_sigabrt(PyObject *self, PyObject *args)
1050{
Victor Stinner7a399122014-09-30 13:40:12 +02001051 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001052 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001053 Py_RETURN_NONE;
1054}
1055
Victor Stinner024e37a2011-03-31 01:31:06 +02001056static PyObject *
1057faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1058{
1059 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001060 int release_gil = 0;
1061 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001062 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001063 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001064 if (release_gil) {
1065 Py_BEGIN_ALLOW_THREADS
1066 Py_FatalError(message);
1067 Py_END_ALLOW_THREADS
1068 }
1069 else {
1070 Py_FatalError(message);
1071 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001072 Py_RETURN_NONE;
1073}
1074
1075#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner404cdc52016-03-23 10:39:17 +01001076#define FAULTHANDLER_STACK_OVERFLOW
1077
Victor Stinner19276f12015-03-23 21:20:27 +01001078#ifdef __INTEL_COMPILER
1079 /* Issue #23654: Turn off ICC's tail call optimization for the
1080 * stack_overflow generator. ICC turns the recursive tail call into
1081 * a loop. */
1082# pragma intel optimization_level 0
1083#endif
1084static
Benjamin Petersonca470632016-09-06 13:47:26 -07001085uintptr_t
1086stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001087{
1088 /* allocate 4096 bytes on the stack at each call */
1089 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001090 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001091 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001092 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001093 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001094 buffer[0] = 1;
1095 buffer[4095] = 0;
1096 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001097}
1098
1099static PyObject *
1100faulthandler_stack_overflow(PyObject *self)
1101{
1102 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001103 uintptr_t sp = (uintptr_t)&depth;
1104 uintptr_t stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001105
Victor Stinner7a399122014-09-30 13:40:12 +02001106 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001107 depth = 0;
Victor Stinner928ad282016-03-23 15:19:12 +01001108 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1109 sp + STACK_OVERFLOW_MAX_SIZE,
1110 &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001111 if (sp < stop)
1112 size = stop - sp;
1113 else
1114 size = sp - stop;
1115 PyErr_Format(PyExc_RuntimeError,
1116 "unable to raise a stack overflow (allocated %zu bytes "
1117 "on the stack, %zu recursive calls)",
1118 size, depth);
1119 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001120}
Victor Stinner928ad282016-03-23 15:19:12 +01001121#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001122
1123
1124static int
1125faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1126{
Victor Stinner024e37a2011-03-31 01:31:06 +02001127#ifdef FAULTHANDLER_LATER
1128 Py_VISIT(thread.file);
1129#endif
1130#ifdef FAULTHANDLER_USER
1131 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001132 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001133 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001134 }
1135#endif
1136 Py_VISIT(fatal_error.file);
1137 return 0;
1138}
1139
Victor Stinner404cdc52016-03-23 10:39:17 +01001140#ifdef MS_WINDOWS
1141static PyObject *
1142faulthandler_raise_exception(PyObject *self, PyObject *args)
1143{
1144 unsigned int code, flags = 0;
1145 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1146 return NULL;
1147 faulthandler_suppress_crash_report();
1148 RaiseException(code, flags, 0, NULL);
1149 Py_RETURN_NONE;
1150}
1151#endif
1152
Victor Stinner024e37a2011-03-31 01:31:06 +02001153PyDoc_STRVAR(module_doc,
1154"faulthandler module.");
1155
1156static PyMethodDef module_methods[] = {
1157 {"enable",
Victor Stinner404cdc52016-03-23 10:39:17 +01001158 (PyCFunction)faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001159 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001160 "enable the fault handler")},
1161 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
1162 PyDoc_STR("disable(): disable the fault handler")},
1163 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
1164 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1165 {"dump_traceback",
1166 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001167 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001168 "dump the traceback of the current thread, or of all threads "
1169 "if all_threads is True, into file")},
1170#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001171 {"dump_traceback_later",
1172 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
1173 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001174 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001175 "or each timeout seconds if repeat is True. If exit is True, "
1176 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001177 {"cancel_dump_traceback_later",
1178 (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
1179 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1180 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001181#endif
1182
1183#ifdef FAULTHANDLER_USER
1184 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001185 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1186 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001187 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001188 "traceback of the current thread, or of all threads if "
1189 "all_threads is True, into file")},
1190 {"unregister",
1191 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1192 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1193 "'signum' registered by register()")},
1194#endif
1195
Victor Stinner50838282014-09-30 13:54:14 +02001196 {"_read_null", faulthandler_read_null, METH_NOARGS,
1197 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001198 "a SIGSEGV or SIGBUS signal depending on the platform")},
1199 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001200 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001201#ifdef WITH_THREAD
1202 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1203 PyDoc_STR("fatal_error_c_thread(): "
1204 "call Py_FatalError() in a new C thread.")},
1205#endif
Victor Stinner9db521c2014-09-30 13:49:09 +02001206 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001207 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001208 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1209 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001210 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1211 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001212#ifdef FAULTHANDLER_STACK_OVERFLOW
Victor Stinner024e37a2011-03-31 01:31:06 +02001213 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1214 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1215#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001216#ifdef MS_WINDOWS
1217 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1218 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1219#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001220 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001221};
1222
1223static struct PyModuleDef module_def = {
1224 PyModuleDef_HEAD_INIT,
1225 "faulthandler",
1226 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001227 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001228 module_methods,
1229 NULL,
1230 faulthandler_traverse,
1231 NULL,
1232 NULL
1233};
1234
1235PyMODINIT_FUNC
1236PyInit_faulthandler(void)
1237{
Victor Stinner404cdc52016-03-23 10:39:17 +01001238 PyObject *m = PyModule_Create(&module_def);
1239 if (m == NULL)
1240 return NULL;
1241
1242 /* Add constants for unit tests */
1243#ifdef MS_WINDOWS
1244 /* RaiseException() codes (prefixed by an underscore) */
1245 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1246 EXCEPTION_ACCESS_VIOLATION))
1247 return NULL;
1248 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1249 EXCEPTION_INT_DIVIDE_BY_ZERO))
1250 return NULL;
1251 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1252 EXCEPTION_STACK_OVERFLOW))
1253 return NULL;
1254
1255 /* RaiseException() flags (prefixed by an underscore) */
1256 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1257 EXCEPTION_NONCONTINUABLE))
1258 return NULL;
1259 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1260 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1261 return NULL;
1262#endif
1263
1264 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001265}
1266
Victor Stinner410dd7d2011-05-11 20:56:08 +02001267/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1268 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001269
1270static int
1271faulthandler_env_options(void)
1272{
1273 PyObject *xoptions, *key, *module, *res;
Victor Stinner88983502013-09-08 11:36:23 +02001274 char *p;
Victor Stinner024e37a2011-03-31 01:31:06 +02001275
Victor Stinner88983502013-09-08 11:36:23 +02001276 if (!((p = Py_GETENV("PYTHONFAULTHANDLER")) && *p != '\0')) {
1277 /* PYTHONFAULTHANDLER environment variable is missing
1278 or an empty string */
Victor Stinner25095b22011-05-26 13:47:08 +02001279 int has_key;
1280
Victor Stinner024e37a2011-03-31 01:31:06 +02001281 xoptions = PySys_GetXOptions();
1282 if (xoptions == NULL)
1283 return -1;
1284
1285 key = PyUnicode_FromString("faulthandler");
1286 if (key == NULL)
1287 return -1;
1288
Victor Stinner25095b22011-05-26 13:47:08 +02001289 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001290 Py_DECREF(key);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001291 if (has_key <= 0)
1292 return has_key;
Victor Stinner024e37a2011-03-31 01:31:06 +02001293 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001294
1295 module = PyImport_ImportModule("faulthandler");
1296 if (module == NULL) {
1297 return -1;
1298 }
Victor Stinner3466bde2016-09-05 18:16:01 -07001299 res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +02001300 Py_DECREF(module);
1301 if (res == NULL)
1302 return -1;
1303 Py_DECREF(res);
1304 return 0;
1305}
1306
1307int _PyFaulthandler_Init(void)
1308{
1309#ifdef HAVE_SIGALTSTACK
1310 int err;
1311
1312 /* Try to allocate an alternate stack for faulthandler() signal handler to
1313 * be able to allocate memory on the stack, even on a stack overflow. If it
1314 * fails, ignore the error. */
1315 stack.ss_flags = 0;
1316 stack.ss_size = SIGSTKSZ;
1317 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1318 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001319 err = sigaltstack(&stack, &old_stack);
Victor Stinner024e37a2011-03-31 01:31:06 +02001320 if (err) {
1321 PyMem_Free(stack.ss_sp);
1322 stack.ss_sp = NULL;
1323 }
1324 }
1325#endif
1326#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001327 thread.file = NULL;
1328 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001329 thread.running = PyThread_allocate_lock();
1330 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001331 PyErr_SetString(PyExc_RuntimeError,
1332 "could not allocate locks for faulthandler");
1333 return -1;
1334 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001335 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001336#endif
1337
1338 return faulthandler_env_options();
1339}
1340
1341void _PyFaulthandler_Fini(void)
1342{
Victor Stinner024e37a2011-03-31 01:31:06 +02001343#ifdef FAULTHANDLER_LATER
1344 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001345 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001346 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001347 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001348 PyThread_free_lock(thread.cancel_event);
1349 thread.cancel_event = NULL;
1350 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001351 if (thread.running) {
1352 PyThread_free_lock(thread.running);
1353 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001354 }
1355#endif
1356
1357#ifdef FAULTHANDLER_USER
1358 /* user */
1359 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001360 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001361 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001362 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001363 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001364 user_signals = NULL;
1365 }
1366#endif
1367
1368 /* fatal */
1369 faulthandler_disable();
1370#ifdef HAVE_SIGALTSTACK
1371 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001372 /* Fetch the current alt stack */
1373 stack_t current_stack;
1374 if (sigaltstack(NULL, &current_stack) == 0) {
1375 if (current_stack.ss_sp == stack.ss_sp) {
1376 /* The current alt stack is the one that we installed.
1377 It is safe to restore the old stack that we found when
1378 we installed ours */
1379 sigaltstack(&old_stack, NULL);
1380 } else {
1381 /* Someone switched to a different alt stack and didn't
1382 restore ours when they were done (if they're done).
1383 There's not much we can do in this unlikely case */
1384 }
1385 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001386 PyMem_Free(stack.ss_sp);
1387 stack.ss_sp = NULL;
1388 }
1389#endif
1390}