blob: 4f3d971bc5270b6f8736c70458bdaf2c0ed70305 [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
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020020#define FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +020021
22#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020023 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
24 SIGILL can be handled by the process, and these signals can only be used
25 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020026# define FAULTHANDLER_USER
27#endif
28
Victor Stinnerc7489a52015-04-01 18:48:58 +020029#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
Victor Stinner024e37a2011-03-31 01:31:06 +020030
Victor Stinnerbd303c12013-11-07 23:07:29 +010031_Py_IDENTIFIER(enable);
32_Py_IDENTIFIER(fileno);
33_Py_IDENTIFIER(flush);
34_Py_IDENTIFIER(stderr);
35
Victor Stinner024e37a2011-03-31 01:31:06 +020036#ifdef HAVE_SIGACTION
37typedef struct sigaction _Py_sighandler_t;
38#else
39typedef PyOS_sighandler_t _Py_sighandler_t;
40#endif
41
42typedef struct {
43 int signum;
44 int enabled;
45 const char* name;
46 _Py_sighandler_t previous;
47 int all_threads;
48} fault_handler_t;
49
50static struct {
51 int enabled;
52 PyObject *file;
53 int fd;
54 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020055 PyInterpreterState *interp;
Victor Stinner46c2b812017-04-21 18:06:13 +020056#ifdef MS_WINDOWS
57 void *exc_handler;
58#endif
Victor Stinner024e37a2011-03-31 01:31:06 +020059} fatal_error = {0, NULL, -1, 0};
60
61#ifdef FAULTHANDLER_LATER
62static struct {
63 PyObject *file;
64 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020065 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020066 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020067 PyInterpreterState *interp;
68 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020069 char *header;
70 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020071 /* The main thread always holds this lock. It is only released when
72 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020073 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020074 PyThread_type_lock cancel_event;
75 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020076 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020077} thread;
78#endif
79
80#ifdef FAULTHANDLER_USER
81typedef struct {
82 int enabled;
83 PyObject *file;
84 int fd;
85 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020086 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020087 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020088 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020089} user_signal_t;
90
91static user_signal_t *user_signals;
92
93/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +020094#ifndef NSIG
95# if defined(_NSIG)
96# define NSIG _NSIG /* For BSD/SysV */
97# elif defined(_SIGMAX)
98# define NSIG (_SIGMAX + 1) /* For QNX */
99# elif defined(SIGMAX)
100# define NSIG (SIGMAX + 1) /* For djgpp */
101# else
102# define NSIG 64 /* Use a reasonable default value */
103# endif
104#endif
105
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200106static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200107#endif /* FAULTHANDLER_USER */
108
109
110static fault_handler_t faulthandler_handlers[] = {
111#ifdef SIGBUS
112 {SIGBUS, 0, "Bus error", },
113#endif
114#ifdef SIGILL
115 {SIGILL, 0, "Illegal instruction", },
116#endif
117 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200118 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200119 /* define SIGSEGV at the end to make it the default choice if searching the
120 handler fails in faulthandler_fatal_error() */
121 {SIGSEGV, 0, "Segmentation fault", }
122};
Victor Stinner404cdc52016-03-23 10:39:17 +0100123static const size_t faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200124 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200125
126#ifdef HAVE_SIGALTSTACK
127static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700128static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200129#endif
130
131
132/* Get the file descriptor of a file by calling its fileno() method and then
133 call its flush() method.
134
135 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100136 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200137
Victor Stinner95bb7142015-03-12 15:32:03 +0100138 On success, return the file descriptor and write the new file into *file_ptr.
139 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200140
Victor Stinner95bb7142015-03-12 15:32:03 +0100141static int
142faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200143{
144 PyObject *result;
145 long fd_long;
146 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100147 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200148
149 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100150 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200151 if (file == NULL) {
152 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100153 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200154 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200155 if (file == Py_None) {
156 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100157 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200158 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200159 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100160 else if (PyLong_Check(file)) {
161 fd = _PyLong_AsInt(file);
162 if (fd == -1 && PyErr_Occurred())
163 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700164 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100165 PyErr_SetString(PyExc_ValueError,
166 "file is not a valid file descripter");
167 return -1;
168 }
169 *file_ptr = NULL;
170 return fd;
171 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200172
Victor Stinner3466bde2016-09-05 18:16:01 -0700173 result = _PyObject_CallMethodId(file, &PyId_fileno, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200174 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100175 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200176
177 fd = -1;
178 if (PyLong_Check(result)) {
179 fd_long = PyLong_AsLong(result);
180 if (0 <= fd_long && fd_long < INT_MAX)
181 fd = (int)fd_long;
182 }
183 Py_DECREF(result);
184
185 if (fd == -1) {
186 PyErr_SetString(PyExc_RuntimeError,
187 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100188 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200189 }
190
Victor Stinner3466bde2016-09-05 18:16:01 -0700191 result = _PyObject_CallMethodId(file, &PyId_flush, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200192 if (result != NULL)
193 Py_DECREF(result);
194 else {
195 /* ignore flush() error */
196 PyErr_Clear();
197 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100198 *file_ptr = file;
199 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200200}
201
Victor Stinnera4de6d82011-04-09 00:47:23 +0200202/* Get the state of the current thread: only call this function if the current
203 thread holds the GIL. Raise an exception on error. */
204static PyThreadState*
205get_thread_state(void)
206{
Victor Stinner861d9ab2016-03-16 22:45:24 +0100207 PyThreadState *tstate = _PyThreadState_UncheckedGet();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200208 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100209 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200210 PyErr_SetString(PyExc_RuntimeError,
211 "unable to get the current thread state");
212 return NULL;
213 }
214 return tstate;
215}
216
Victor Stinnerc7489a52015-04-01 18:48:58 +0200217static void
218faulthandler_dump_traceback(int fd, int all_threads,
219 PyInterpreterState *interp)
220{
221 static volatile int reentrant = 0;
222 PyThreadState *tstate;
223
224 if (reentrant)
225 return;
226
227 reentrant = 1;
228
Victor Stinnerc7489a52015-04-01 18:48:58 +0200229 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
230 are thus delivered to the thread that caused the fault. Get the Python
231 thread state of the current thread.
232
233 PyThreadState_Get() doesn't give the state of the thread that caused the
234 fault if the thread released the GIL, and so this function cannot be
235 used. Read the thread local storage (TLS) instead: call
236 PyGILState_GetThisThreadState(). */
237 tstate = PyGILState_GetThisThreadState();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200238
Victor Stinner861d9ab2016-03-16 22:45:24 +0100239 if (all_threads) {
240 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
241 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200242 else {
243 if (tstate != NULL)
244 _Py_DumpTraceback(fd, tstate);
245 }
246
247 reentrant = 0;
248}
249
Victor Stinner024e37a2011-03-31 01:31:06 +0200250static PyObject*
251faulthandler_dump_traceback_py(PyObject *self,
252 PyObject *args, PyObject *kwargs)
253{
254 static char *kwlist[] = {"file", "all_threads", NULL};
255 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200256 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200257 PyThreadState *tstate;
258 const char *errmsg;
259 int fd;
260
261 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
262 "|Oi:dump_traceback", kwlist,
263 &file, &all_threads))
264 return NULL;
265
Victor Stinner95bb7142015-03-12 15:32:03 +0100266 fd = faulthandler_get_fileno(&file);
267 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200268 return NULL;
269
Victor Stinnera4de6d82011-04-09 00:47:23 +0200270 tstate = get_thread_state();
271 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200272 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200273
274 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100275 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200276 if (errmsg != NULL) {
277 PyErr_SetString(PyExc_RuntimeError, errmsg);
278 return NULL;
279 }
280 }
281 else {
282 _Py_DumpTraceback(fd, tstate);
283 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200284
285 if (PyErr_CheckSignals())
286 return NULL;
287
Victor Stinner024e37a2011-03-31 01:31:06 +0200288 Py_RETURN_NONE;
289}
290
Victor Stinner404cdc52016-03-23 10:39:17 +0100291static void
292faulthandler_disable_fatal_handler(fault_handler_t *handler)
293{
294 if (!handler->enabled)
295 return;
296 handler->enabled = 0;
297#ifdef HAVE_SIGACTION
298 (void)sigaction(handler->signum, &handler->previous, NULL);
299#else
300 (void)signal(handler->signum, handler->previous);
301#endif
302}
303
Victor Stinner024e37a2011-03-31 01:31:06 +0200304
Victor Stinner410dd7d2011-05-11 20:56:08 +0200305/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200306
307 Display the current Python traceback, restore the previous handler and call
308 the previous handler.
309
Victor Stinner410dd7d2011-05-11 20:56:08 +0200310 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200311 signal handler would not be called (for an unknown reason). The execution of
312 the program continues at faulthandler_fatal_error() exit, but the same
313 instruction will raise the same fault (signal), and so the previous handler
314 will be called.
315
Victor Stinner410dd7d2011-05-11 20:56:08 +0200316 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200317
318static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200319faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200320{
321 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100322 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200323 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200324 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200325
326 if (!fatal_error.enabled)
327 return;
328
329 for (i=0; i < faulthandler_nsignals; i++) {
330 handler = &faulthandler_handlers[i];
331 if (handler->signum == signum)
332 break;
333 }
334 if (handler == NULL) {
335 /* faulthandler_nsignals == 0 (unlikely) */
336 return;
337 }
338
339 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100340 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200341
342 PUTS(fd, "Fatal Python error: ");
343 PUTS(fd, handler->name);
344 PUTS(fd, "\n\n");
345
Victor Stinnerc7489a52015-04-01 18:48:58 +0200346 faulthandler_dump_traceback(fd, fatal_error.all_threads,
347 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200348
Victor Stinnerc9256172011-05-07 12:20:11 +0200349 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200350#ifdef MS_WINDOWS
351 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200352 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200353 handler, because the Windows signal handler would not be called */
354 return;
355 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200356#endif
R David Murrayfc069992013-12-13 20:52:19 -0500357 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200358 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
359 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200360}
361
Victor Stinner404cdc52016-03-23 10:39:17 +0100362#ifdef MS_WINDOWS
363static LONG WINAPI
364faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
365{
366 const int fd = fatal_error.fd;
367 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100368 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100369
Steve Dowere6a23c82017-06-05 15:54:15 -0700370 /* bpo-30557: only log fatal exceptions */
371 if (!(code & 0x80000000)) {
Victor Stinner412a5e72016-03-23 14:44:14 +0100372 /* call the next exception handler */
373 return EXCEPTION_CONTINUE_SEARCH;
374 }
375
376 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100377 switch (code)
378 {
379 /* only format most common errors */
380 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
381 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
382 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
383 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
384 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
385 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
386 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
387 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700388 PUTS(fd, "code 0x");
389 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100390 }
391 PUTS(fd, "\n\n");
392
393 if (code == EXCEPTION_ACCESS_VIOLATION) {
394 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200395 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100396 fault_handler_t *handler = &faulthandler_handlers[i];
397 if (handler->signum == SIGSEGV) {
398 faulthandler_disable_fatal_handler(handler);
399 break;
400 }
401 }
402 }
403
404 faulthandler_dump_traceback(fd, fatal_error.all_threads,
405 fatal_error.interp);
406
407 /* call the next exception handler */
408 return EXCEPTION_CONTINUE_SEARCH;
409}
410#endif
411
Victor Stinnerd727e232011-04-01 12:13:55 +0200412/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200413
doko@ubuntu.combc731502016-05-18 01:06:01 +0200414static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100415faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200416{
Victor Stinner404cdc52016-03-23 10:39:17 +0100417 if (fatal_error.enabled) {
418 return 0;
419 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100420 fatal_error.enabled = 1;
421
Victor Stinner46c2b812017-04-21 18:06:13 +0200422 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100423 fault_handler_t *handler;
424#ifdef HAVE_SIGACTION
425 struct sigaction action;
426#endif
427 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100428
Victor Stinner928ad282016-03-23 15:19:12 +0100429 handler = &faulthandler_handlers[i];
430 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100431#ifdef HAVE_SIGACTION
432 action.sa_handler = faulthandler_fatal_error;
433 sigemptyset(&action.sa_mask);
434 /* Do not prevent the signal from being received from within
435 its own signal handler */
436 action.sa_flags = SA_NODEFER;
437#ifdef HAVE_SIGALTSTACK
438 if (stack.ss_sp != NULL) {
439 /* Call the signal handler on an alternate signal stack
440 provided by sigaltstack() */
441 action.sa_flags |= SA_ONSTACK;
442 }
443#endif
444 err = sigaction(handler->signum, &action, &handler->previous);
445#else
446 handler->previous = signal(handler->signum,
447 faulthandler_fatal_error);
448 err = (handler->previous == SIG_ERR);
449#endif
450 if (err) {
451 PyErr_SetFromErrno(PyExc_RuntimeError);
452 return -1;
453 }
454
455 handler->enabled = 1;
456 }
457
458#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200459 assert(fatal_error.exc_handler == NULL);
460 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100461#endif
462 return 0;
463}
464
465static PyObject*
466faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
467{
468 static char *kwlist[] = {"file", "all_threads", NULL};
469 PyObject *file = NULL;
470 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200471 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200472 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200473
474 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
475 "|Oi:enable", kwlist, &file, &all_threads))
476 return NULL;
477
Victor Stinner95bb7142015-03-12 15:32:03 +0100478 fd = faulthandler_get_fileno(&file);
479 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200480 return NULL;
481
Victor Stinnera4de6d82011-04-09 00:47:23 +0200482 tstate = get_thread_state();
483 if (tstate == NULL)
484 return NULL;
485
Victor Stinner95bb7142015-03-12 15:32:03 +0100486 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300487 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200488 fatal_error.fd = fd;
489 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200490 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200491
Victor Stinner404cdc52016-03-23 10:39:17 +0100492 if (faulthandler_enable() < 0) {
493 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200494 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100495
Victor Stinner024e37a2011-03-31 01:31:06 +0200496 Py_RETURN_NONE;
497}
498
499static void
500faulthandler_disable(void)
501{
Victor Stinner024e37a2011-03-31 01:31:06 +0200502 if (fatal_error.enabled) {
503 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200504 for (size_t i=0; i < faulthandler_nsignals; i++) {
505 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200506 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100507 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200508 }
509 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200510#ifdef MS_WINDOWS
511 if (fatal_error.exc_handler != NULL) {
512 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
513 fatal_error.exc_handler = NULL;
514 }
515#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200516 Py_CLEAR(fatal_error.file);
517}
518
519static PyObject*
520faulthandler_disable_py(PyObject *self)
521{
522 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200523 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200524 }
525 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200526 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200527}
528
529static PyObject*
530faulthandler_is_enabled(PyObject *self)
531{
532 return PyBool_FromLong(fatal_error.enabled);
533}
534
535#ifdef FAULTHANDLER_LATER
536
537static void
538faulthandler_thread(void *unused)
539{
540 PyLockStatus st;
541 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200542 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200543#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200544 sigset_t set;
545
546 /* we don't want to receive any signal */
547 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200548 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200549#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200550
551 do {
552 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200553 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200554 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200555 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200556 break;
557 }
558 /* Timeout => dump traceback */
559 assert(st == PY_LOCK_FAILURE);
560
Victor Stinnerc7489a52015-04-01 18:48:58 +0200561 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200562
Victor Stinner861d9ab2016-03-16 22:45:24 +0100563 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200564 ok = (errmsg == NULL);
565
566 if (thread.exit)
567 _exit(1);
568 } while (ok && thread.repeat);
569
570 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200571 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200572}
573
574static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200575cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200576{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200577 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200578 PyThread_release_lock(thread.cancel_event);
579
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200580 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200581 PyThread_acquire_lock(thread.running, 1);
582 PyThread_release_lock(thread.running);
583
584 /* The main thread should always hold the cancel_event lock */
585 PyThread_acquire_lock(thread.cancel_event, 1);
586
Victor Stinner024e37a2011-03-31 01:31:06 +0200587 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200588 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200589 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200590 thread.header = NULL;
591 }
592}
593
594static char*
595format_timeout(double timeout)
596{
597 unsigned long us, sec, min, hour;
598 double intpart, fracpart;
599 char buffer[100];
600
601 fracpart = modf(timeout, &intpart);
602 sec = (unsigned long)intpart;
603 us = (unsigned long)(fracpart * 1e6);
604 min = sec / 60;
605 sec %= 60;
606 hour = min / 60;
607 min %= 60;
608
609 if (us != 0)
610 PyOS_snprintf(buffer, sizeof(buffer),
611 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
612 hour, min, sec, us);
613 else
614 PyOS_snprintf(buffer, sizeof(buffer),
615 "Timeout (%lu:%02lu:%02lu)!\n",
616 hour, min, sec);
617
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200618 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200619}
620
621static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200622faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200623 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200624{
625 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
626 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200627 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200628 int repeat = 0;
629 PyObject *file = NULL;
630 int fd;
631 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200632 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200633 char *header;
634 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200635
636 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Georg Brandldeb92b52012-09-22 08:58:55 +0200637 "d|iOi:dump_traceback_later", kwlist,
Victor Stinner024e37a2011-03-31 01:31:06 +0200638 &timeout, &repeat, &file, &exit))
639 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200640 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200641 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
642 return NULL;
643 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200644 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200645 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200646 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
647 return NULL;
648 }
649
Victor Stinnera4de6d82011-04-09 00:47:23 +0200650 tstate = get_thread_state();
651 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200652 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200653
Victor Stinner95bb7142015-03-12 15:32:03 +0100654 fd = faulthandler_get_fileno(&file);
655 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200656 return NULL;
657
Victor Stinnerc790a532011-04-08 13:39:59 +0200658 /* format the timeout */
659 header = format_timeout(timeout);
660 if (header == NULL)
661 return PyErr_NoMemory();
662 header_len = strlen(header);
663
Victor Stinner024e37a2011-03-31 01:31:06 +0200664 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200665 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200666
Victor Stinner95bb7142015-03-12 15:32:03 +0100667 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300668 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200669 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200670 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200671 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200672 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200673 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200674 thread.header = header;
675 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200676
677 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200678 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200679
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200680 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200681 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200682 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200683 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200684 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200685 PyErr_SetString(PyExc_RuntimeError,
686 "unable to start watchdog thread");
687 return NULL;
688 }
689
690 Py_RETURN_NONE;
691}
692
693static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200694faulthandler_cancel_dump_traceback_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200695{
Georg Brandldeb92b52012-09-22 08:58:55 +0200696 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200697 Py_RETURN_NONE;
698}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200699#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200700
701#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200702static int
703faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
704{
705#ifdef HAVE_SIGACTION
706 struct sigaction action;
707 action.sa_handler = faulthandler_user;
708 sigemptyset(&action.sa_mask);
709 /* if the signal is received while the kernel is executing a system
710 call, try to restart the system call instead of interrupting it and
711 return EINTR. */
712 action.sa_flags = SA_RESTART;
713 if (chain) {
714 /* do not prevent the signal from being received from within its
715 own signal handler */
716 action.sa_flags = SA_NODEFER;
717 }
718#ifdef HAVE_SIGALTSTACK
719 if (stack.ss_sp != NULL) {
720 /* Call the signal handler on an alternate signal stack
721 provided by sigaltstack() */
722 action.sa_flags |= SA_ONSTACK;
723 }
724#endif
725 return sigaction(signum, &action, p_previous);
726#else
727 _Py_sighandler_t previous;
728 previous = signal(signum, faulthandler_user);
729 if (p_previous != NULL)
730 *p_previous = previous;
731 return (previous == SIG_ERR);
732#endif
733}
734
Victor Stinner024e37a2011-03-31 01:31:06 +0200735/* Handler of user signals (e.g. SIGUSR1).
736
737 Dump the traceback of the current thread, or of all threads if
738 thread.all_threads is true.
739
740 This function is signal safe and should only call signal safe functions. */
741
742static void
743faulthandler_user(int signum)
744{
745 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200746 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200747
748 user = &user_signals[signum];
749 if (!user->enabled)
750 return;
751
Victor Stinnerc7489a52015-04-01 18:48:58 +0200752 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200753
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200754#ifdef HAVE_SIGACTION
755 if (user->chain) {
756 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200757 errno = save_errno;
758
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200759 /* call the previous signal handler */
760 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200761
762 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200763 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200764 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200765 }
766#else
767 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200768 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200769 /* call the previous signal handler */
770 user->previous(signum);
771 }
772#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200773}
774
775static int
776check_signum(int signum)
777{
Victor Stinner46c2b812017-04-21 18:06:13 +0200778 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200779 if (faulthandler_handlers[i].signum == signum) {
780 PyErr_Format(PyExc_RuntimeError,
781 "signal %i cannot be registered, "
782 "use enable() instead",
783 signum);
784 return 0;
785 }
786 }
787 if (signum < 1 || NSIG <= signum) {
788 PyErr_SetString(PyExc_ValueError, "signal number out of range");
789 return 0;
790 }
791 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200792}
793
794static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200795faulthandler_register_py(PyObject *self,
796 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200797{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200798 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200799 int signum;
800 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200801 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200802 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200803 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200804 user_signal_t *user;
805 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200806 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200807 int err;
808
809 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200810 "i|Oii:register", kwlist,
811 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200812 return NULL;
813
Victor Stinner44378d42011-04-01 15:37:12 +0200814 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200815 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200816
Victor Stinnera4de6d82011-04-09 00:47:23 +0200817 tstate = get_thread_state();
818 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200819 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200820
Victor Stinner95bb7142015-03-12 15:32:03 +0100821 fd = faulthandler_get_fileno(&file);
822 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200823 return NULL;
824
825 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200826 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200827 if (user_signals == NULL)
828 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200829 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200830 }
831 user = &user_signals[signum];
832
833 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200834 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200835 if (err) {
836 PyErr_SetFromErrno(PyExc_OSError);
837 return NULL;
838 }
Victor Stinner8d379542013-07-02 00:14:56 +0200839
840 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200841 }
842
Victor Stinner95bb7142015-03-12 15:32:03 +0100843 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300844 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200845 user->fd = fd;
846 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200847 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200848 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200849 user->enabled = 1;
850
851 Py_RETURN_NONE;
852}
853
854static int
855faulthandler_unregister(user_signal_t *user, int signum)
856{
Victor Stinnera01ca122011-04-01 12:56:17 +0200857 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200858 return 0;
859 user->enabled = 0;
860#ifdef HAVE_SIGACTION
861 (void)sigaction(signum, &user->previous, NULL);
862#else
863 (void)signal(signum, user->previous);
864#endif
865 Py_CLEAR(user->file);
866 user->fd = -1;
867 return 1;
868}
869
870static PyObject*
871faulthandler_unregister_py(PyObject *self, PyObject *args)
872{
873 int signum;
874 user_signal_t *user;
875 int change;
876
877 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
878 return NULL;
879
Victor Stinner44378d42011-04-01 15:37:12 +0200880 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200881 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200882
Victor Stinnercfa71232011-04-08 12:48:15 +0200883 if (user_signals == NULL)
884 Py_RETURN_FALSE;
885
Victor Stinner024e37a2011-03-31 01:31:06 +0200886 user = &user_signals[signum];
887 change = faulthandler_unregister(user, signum);
888 return PyBool_FromLong(change);
889}
890#endif /* FAULTHANDLER_USER */
891
892
Victor Stinner7a399122014-09-30 13:40:12 +0200893static void
894faulthandler_suppress_crash_report(void)
895{
896#ifdef MS_WINDOWS
897 UINT mode;
898
899 /* Configure Windows to not display the Windows Error Reporting dialog */
900 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
901 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
902#endif
903
904#ifdef HAVE_SYS_RESOURCE_H
905 struct rlimit rl;
906
907 /* Disable creation of core dump */
908 if (getrlimit(RLIMIT_CORE, &rl) != 0) {
909 rl.rlim_cur = 0;
910 setrlimit(RLIMIT_CORE, &rl);
911 }
912#endif
913
914#ifdef _MSC_VER
915 /* Visual Studio: configure abort() to not display an error message nor
916 open a popup asking to report the fault. */
917 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
918#endif
919}
920
Victor Stinner024e37a2011-03-31 01:31:06 +0200921static PyObject *
922faulthandler_read_null(PyObject *self, PyObject *args)
923{
Victor Stinnera2477202012-01-30 00:07:43 +0100924 volatile int *x;
925 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +0100926
Victor Stinner7a399122014-09-30 13:40:12 +0200927 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +0100928 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +0200929 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +0200930 return PyLong_FromLong(y);
931
932}
933
Victor Stinner50838282014-09-30 13:54:14 +0200934static void
935faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200936{
Victor Stinner7a399122014-09-30 13:40:12 +0200937 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +0200938#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200939 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
940 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200941 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200942 SIGSEGV was raised by the kernel because of a fault, and so if the
943 program retries to execute the same instruction, the fault will be
944 raised again.
945
946 Here the fault is simulated by a fake SIGSEGV signal raised by the
947 application. We have to raise SIGSEGV at lease twice: once for
948 faulthandler_fatal_error(), and one more time for the previous signal
949 handler. */
950 while(1)
951 raise(SIGSEGV);
952#else
953 raise(SIGSEGV);
954#endif
Victor Stinner50838282014-09-30 13:54:14 +0200955}
956
957static PyObject *
958faulthandler_sigsegv(PyObject *self, PyObject *args)
959{
960 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +0100961 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +0200962 return NULL;
963
964 if (release_gil) {
965 Py_BEGIN_ALLOW_THREADS
966 faulthandler_raise_sigsegv();
967 Py_END_ALLOW_THREADS
968 } else {
969 faulthandler_raise_sigsegv();
970 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200971 Py_RETURN_NONE;
972}
973
Victor Stinner861d9ab2016-03-16 22:45:24 +0100974static void
975faulthandler_fatal_error_thread(void *plock)
976{
Victor Stinner9a2329f2016-12-05 17:56:36 +0100977#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +0100978 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +0100979#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +0100980
981 Py_FatalError("in new thread");
982
Victor Stinner9a2329f2016-12-05 17:56:36 +0100983#ifndef __clang__
984 /* Issue #28152: Py_FatalError() is declared with
985 __attribute__((__noreturn__)). GCC emits a warning without
986 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
987 emits a warning on the return. */
988
Victor Stinner861d9ab2016-03-16 22:45:24 +0100989 /* notify the caller that we are done */
990 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +0100991#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +0100992}
993
994static PyObject *
995faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
996{
997 long thread;
998 PyThread_type_lock lock;
999
1000 faulthandler_suppress_crash_report();
1001
1002 lock = PyThread_allocate_lock();
1003 if (lock == NULL)
1004 return PyErr_NoMemory();
1005
1006 PyThread_acquire_lock(lock, WAIT_LOCK);
1007
1008 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1009 if (thread == -1) {
1010 PyThread_free_lock(lock);
1011 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1012 return NULL;
1013 }
1014
1015 /* wait until the thread completes: it will never occur, since Py_FatalError()
1016 exits the process immedialty. */
1017 PyThread_acquire_lock(lock, WAIT_LOCK);
1018 PyThread_release_lock(lock);
1019 PyThread_free_lock(lock);
1020
1021 Py_RETURN_NONE;
1022}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001023
Victor Stinner024e37a2011-03-31 01:31:06 +02001024static PyObject *
1025faulthandler_sigfpe(PyObject *self, PyObject *args)
1026{
1027 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1028 PowerPC. Use volatile to disable compile-time optimizations. */
1029 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001030 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001031 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001032 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1033 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001034 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001035 /* This line is never reached, but we pretend to make something with z
1036 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001037 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001038}
1039
Victor Stinnerd727e232011-04-01 12:13:55 +02001040static PyObject *
1041faulthandler_sigabrt(PyObject *self, PyObject *args)
1042{
Victor Stinner7a399122014-09-30 13:40:12 +02001043 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001044 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001045 Py_RETURN_NONE;
1046}
1047
Victor Stinner024e37a2011-03-31 01:31:06 +02001048static PyObject *
1049faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1050{
1051 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001052 int release_gil = 0;
1053 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001054 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001055 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001056 if (release_gil) {
1057 Py_BEGIN_ALLOW_THREADS
1058 Py_FatalError(message);
1059 Py_END_ALLOW_THREADS
1060 }
1061 else {
1062 Py_FatalError(message);
1063 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001064 Py_RETURN_NONE;
1065}
1066
1067#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner404cdc52016-03-23 10:39:17 +01001068#define FAULTHANDLER_STACK_OVERFLOW
1069
Victor Stinner19276f12015-03-23 21:20:27 +01001070#ifdef __INTEL_COMPILER
1071 /* Issue #23654: Turn off ICC's tail call optimization for the
1072 * stack_overflow generator. ICC turns the recursive tail call into
1073 * a loop. */
1074# pragma intel optimization_level 0
1075#endif
1076static
Benjamin Petersonca470632016-09-06 13:47:26 -07001077uintptr_t
1078stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001079{
1080 /* allocate 4096 bytes on the stack at each call */
1081 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001082 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001083 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001084 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001085 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001086 buffer[0] = 1;
1087 buffer[4095] = 0;
1088 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001089}
1090
1091static PyObject *
1092faulthandler_stack_overflow(PyObject *self)
1093{
1094 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001095 uintptr_t sp = (uintptr_t)&depth;
1096 uintptr_t stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001097
Victor Stinner7a399122014-09-30 13:40:12 +02001098 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001099 depth = 0;
Victor Stinner928ad282016-03-23 15:19:12 +01001100 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1101 sp + STACK_OVERFLOW_MAX_SIZE,
1102 &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001103 if (sp < stop)
1104 size = stop - sp;
1105 else
1106 size = sp - stop;
1107 PyErr_Format(PyExc_RuntimeError,
1108 "unable to raise a stack overflow (allocated %zu bytes "
1109 "on the stack, %zu recursive calls)",
1110 size, depth);
1111 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001112}
Victor Stinner928ad282016-03-23 15:19:12 +01001113#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001114
1115
1116static int
1117faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1118{
Victor Stinner024e37a2011-03-31 01:31:06 +02001119#ifdef FAULTHANDLER_LATER
1120 Py_VISIT(thread.file);
1121#endif
1122#ifdef FAULTHANDLER_USER
1123 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001124 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001125 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001126 }
1127#endif
1128 Py_VISIT(fatal_error.file);
1129 return 0;
1130}
1131
Victor Stinner404cdc52016-03-23 10:39:17 +01001132#ifdef MS_WINDOWS
1133static PyObject *
1134faulthandler_raise_exception(PyObject *self, PyObject *args)
1135{
1136 unsigned int code, flags = 0;
1137 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1138 return NULL;
1139 faulthandler_suppress_crash_report();
1140 RaiseException(code, flags, 0, NULL);
1141 Py_RETURN_NONE;
1142}
1143#endif
1144
Victor Stinner024e37a2011-03-31 01:31:06 +02001145PyDoc_STRVAR(module_doc,
1146"faulthandler module.");
1147
1148static PyMethodDef module_methods[] = {
1149 {"enable",
Victor Stinner404cdc52016-03-23 10:39:17 +01001150 (PyCFunction)faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001151 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001152 "enable the fault handler")},
1153 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
1154 PyDoc_STR("disable(): disable the fault handler")},
1155 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
1156 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1157 {"dump_traceback",
1158 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001159 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001160 "dump the traceback of the current thread, or of all threads "
1161 "if all_threads is True, into file")},
1162#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001163 {"dump_traceback_later",
1164 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
1165 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001166 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001167 "or each timeout seconds if repeat is True. If exit is True, "
1168 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001169 {"cancel_dump_traceback_later",
1170 (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
1171 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1172 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001173#endif
1174
1175#ifdef FAULTHANDLER_USER
1176 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001177 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1178 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001179 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001180 "traceback of the current thread, or of all threads if "
1181 "all_threads is True, into file")},
1182 {"unregister",
1183 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1184 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1185 "'signum' registered by register()")},
1186#endif
1187
Victor Stinner50838282014-09-30 13:54:14 +02001188 {"_read_null", faulthandler_read_null, METH_NOARGS,
1189 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001190 "a SIGSEGV or SIGBUS signal depending on the platform")},
1191 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001192 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001193 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1194 PyDoc_STR("fatal_error_c_thread(): "
1195 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001196 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001197 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001198 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1199 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001200 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1201 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001202#ifdef FAULTHANDLER_STACK_OVERFLOW
Victor Stinner024e37a2011-03-31 01:31:06 +02001203 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1204 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1205#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001206#ifdef MS_WINDOWS
1207 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1208 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1209#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001210 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001211};
1212
1213static struct PyModuleDef module_def = {
1214 PyModuleDef_HEAD_INIT,
1215 "faulthandler",
1216 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001217 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001218 module_methods,
1219 NULL,
1220 faulthandler_traverse,
1221 NULL,
1222 NULL
1223};
1224
1225PyMODINIT_FUNC
1226PyInit_faulthandler(void)
1227{
Victor Stinner404cdc52016-03-23 10:39:17 +01001228 PyObject *m = PyModule_Create(&module_def);
1229 if (m == NULL)
1230 return NULL;
1231
1232 /* Add constants for unit tests */
1233#ifdef MS_WINDOWS
1234 /* RaiseException() codes (prefixed by an underscore) */
1235 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1236 EXCEPTION_ACCESS_VIOLATION))
1237 return NULL;
1238 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1239 EXCEPTION_INT_DIVIDE_BY_ZERO))
1240 return NULL;
1241 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1242 EXCEPTION_STACK_OVERFLOW))
1243 return NULL;
1244
1245 /* RaiseException() flags (prefixed by an underscore) */
1246 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1247 EXCEPTION_NONCONTINUABLE))
1248 return NULL;
1249 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1250 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1251 return NULL;
1252#endif
1253
1254 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001255}
1256
Victor Stinner410dd7d2011-05-11 20:56:08 +02001257/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1258 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001259
1260static int
1261faulthandler_env_options(void)
1262{
1263 PyObject *xoptions, *key, *module, *res;
Victor Stinner88983502013-09-08 11:36:23 +02001264 char *p;
Victor Stinner024e37a2011-03-31 01:31:06 +02001265
Victor Stinner88983502013-09-08 11:36:23 +02001266 if (!((p = Py_GETENV("PYTHONFAULTHANDLER")) && *p != '\0')) {
1267 /* PYTHONFAULTHANDLER environment variable is missing
1268 or an empty string */
Victor Stinner25095b22011-05-26 13:47:08 +02001269 int has_key;
1270
Victor Stinner024e37a2011-03-31 01:31:06 +02001271 xoptions = PySys_GetXOptions();
1272 if (xoptions == NULL)
1273 return -1;
1274
1275 key = PyUnicode_FromString("faulthandler");
1276 if (key == NULL)
1277 return -1;
1278
Victor Stinner25095b22011-05-26 13:47:08 +02001279 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001280 Py_DECREF(key);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001281 if (has_key <= 0)
1282 return has_key;
Victor Stinner024e37a2011-03-31 01:31:06 +02001283 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001284
1285 module = PyImport_ImportModule("faulthandler");
1286 if (module == NULL) {
1287 return -1;
1288 }
Victor Stinner3466bde2016-09-05 18:16:01 -07001289 res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +02001290 Py_DECREF(module);
1291 if (res == NULL)
1292 return -1;
1293 Py_DECREF(res);
1294 return 0;
1295}
1296
1297int _PyFaulthandler_Init(void)
1298{
1299#ifdef HAVE_SIGALTSTACK
1300 int err;
1301
1302 /* Try to allocate an alternate stack for faulthandler() signal handler to
1303 * be able to allocate memory on the stack, even on a stack overflow. If it
1304 * fails, ignore the error. */
1305 stack.ss_flags = 0;
1306 stack.ss_size = SIGSTKSZ;
1307 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1308 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001309 err = sigaltstack(&stack, &old_stack);
Victor Stinner024e37a2011-03-31 01:31:06 +02001310 if (err) {
1311 PyMem_Free(stack.ss_sp);
1312 stack.ss_sp = NULL;
1313 }
1314 }
1315#endif
1316#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001317 thread.file = NULL;
1318 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001319 thread.running = PyThread_allocate_lock();
1320 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001321 PyErr_SetString(PyExc_RuntimeError,
1322 "could not allocate locks for faulthandler");
1323 return -1;
1324 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001325 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001326#endif
1327
1328 return faulthandler_env_options();
1329}
1330
1331void _PyFaulthandler_Fini(void)
1332{
Victor Stinner024e37a2011-03-31 01:31:06 +02001333#ifdef FAULTHANDLER_LATER
1334 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001335 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001336 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001337 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001338 PyThread_free_lock(thread.cancel_event);
1339 thread.cancel_event = NULL;
1340 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001341 if (thread.running) {
1342 PyThread_free_lock(thread.running);
1343 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001344 }
1345#endif
1346
1347#ifdef FAULTHANDLER_USER
1348 /* user */
1349 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001350 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001351 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001352 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001353 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001354 user_signals = NULL;
1355 }
1356#endif
1357
1358 /* fatal */
1359 faulthandler_disable();
1360#ifdef HAVE_SIGALTSTACK
1361 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001362 /* Fetch the current alt stack */
1363 stack_t current_stack;
1364 if (sigaltstack(NULL, &current_stack) == 0) {
1365 if (current_stack.ss_sp == stack.ss_sp) {
1366 /* The current alt stack is the one that we installed.
1367 It is safe to restore the old stack that we found when
1368 we installed ours */
1369 sigaltstack(&old_stack, NULL);
1370 } else {
1371 /* Someone switched to a different alt stack and didn't
1372 restore ours when they were done (if they're done).
1373 There's not much we can do in this unlikely case */
1374 }
1375 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001376 PyMem_Free(stack.ss_sp);
1377 stack.ss_sp = NULL;
1378 }
1379#endif
1380}