blob: dba646b12870b84d9ba93a1ad97a778dacf1e35e [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
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900235 used. Read the thread specific storage (TSS) instead: call
Victor Stinnerc7489a52015-04-01 18:48:58 +0200236 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
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700363static int
364faulthandler_ignore_exception(DWORD code)
365{
366 /* bpo-30557: ignore exceptions which are not errors */
367 if (!(code & 0x80000000)) {
368 return 1;
369 }
370 /* bpo-31701: ignore MSC and COM exceptions
371 E0000000 + code */
372 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
373 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
374 return 1;
375 }
376 /* Interesting exception: log it with the Python traceback */
377 return 0;
378}
379
Victor Stinner404cdc52016-03-23 10:39:17 +0100380static LONG WINAPI
381faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
382{
383 const int fd = fatal_error.fd;
384 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100385 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100386
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700387 if (faulthandler_ignore_exception(code)) {
388 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100389 return EXCEPTION_CONTINUE_SEARCH;
390 }
391
392 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100393 switch (code)
394 {
395 /* only format most common errors */
396 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
397 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
398 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
399 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
400 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
401 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
402 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
403 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700404 PUTS(fd, "code 0x");
405 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100406 }
407 PUTS(fd, "\n\n");
408
409 if (code == EXCEPTION_ACCESS_VIOLATION) {
410 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200411 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100412 fault_handler_t *handler = &faulthandler_handlers[i];
413 if (handler->signum == SIGSEGV) {
414 faulthandler_disable_fatal_handler(handler);
415 break;
416 }
417 }
418 }
419
420 faulthandler_dump_traceback(fd, fatal_error.all_threads,
421 fatal_error.interp);
422
423 /* call the next exception handler */
424 return EXCEPTION_CONTINUE_SEARCH;
425}
426#endif
427
Victor Stinnerd727e232011-04-01 12:13:55 +0200428/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200429
doko@ubuntu.combc731502016-05-18 01:06:01 +0200430static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100431faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200432{
Victor Stinner404cdc52016-03-23 10:39:17 +0100433 if (fatal_error.enabled) {
434 return 0;
435 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100436 fatal_error.enabled = 1;
437
Victor Stinner46c2b812017-04-21 18:06:13 +0200438 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100439 fault_handler_t *handler;
440#ifdef HAVE_SIGACTION
441 struct sigaction action;
442#endif
443 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100444
Victor Stinner928ad282016-03-23 15:19:12 +0100445 handler = &faulthandler_handlers[i];
446 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100447#ifdef HAVE_SIGACTION
448 action.sa_handler = faulthandler_fatal_error;
449 sigemptyset(&action.sa_mask);
450 /* Do not prevent the signal from being received from within
451 its own signal handler */
452 action.sa_flags = SA_NODEFER;
453#ifdef HAVE_SIGALTSTACK
454 if (stack.ss_sp != NULL) {
455 /* Call the signal handler on an alternate signal stack
456 provided by sigaltstack() */
457 action.sa_flags |= SA_ONSTACK;
458 }
459#endif
460 err = sigaction(handler->signum, &action, &handler->previous);
461#else
462 handler->previous = signal(handler->signum,
463 faulthandler_fatal_error);
464 err = (handler->previous == SIG_ERR);
465#endif
466 if (err) {
467 PyErr_SetFromErrno(PyExc_RuntimeError);
468 return -1;
469 }
470
471 handler->enabled = 1;
472 }
473
474#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200475 assert(fatal_error.exc_handler == NULL);
476 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100477#endif
478 return 0;
479}
480
481static PyObject*
482faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
483{
484 static char *kwlist[] = {"file", "all_threads", NULL};
485 PyObject *file = NULL;
486 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200487 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200488 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200489
490 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
491 "|Oi:enable", kwlist, &file, &all_threads))
492 return NULL;
493
Victor Stinner95bb7142015-03-12 15:32:03 +0100494 fd = faulthandler_get_fileno(&file);
495 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200496 return NULL;
497
Victor Stinnera4de6d82011-04-09 00:47:23 +0200498 tstate = get_thread_state();
499 if (tstate == NULL)
500 return NULL;
501
Victor Stinner95bb7142015-03-12 15:32:03 +0100502 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300503 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200504 fatal_error.fd = fd;
505 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200506 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200507
Victor Stinner404cdc52016-03-23 10:39:17 +0100508 if (faulthandler_enable() < 0) {
509 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200510 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100511
Victor Stinner024e37a2011-03-31 01:31:06 +0200512 Py_RETURN_NONE;
513}
514
515static void
516faulthandler_disable(void)
517{
Victor Stinner024e37a2011-03-31 01:31:06 +0200518 if (fatal_error.enabled) {
519 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200520 for (size_t i=0; i < faulthandler_nsignals; i++) {
521 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200522 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100523 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200524 }
525 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200526#ifdef MS_WINDOWS
527 if (fatal_error.exc_handler != NULL) {
528 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
529 fatal_error.exc_handler = NULL;
530 }
531#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200532 Py_CLEAR(fatal_error.file);
533}
534
535static PyObject*
536faulthandler_disable_py(PyObject *self)
537{
538 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200539 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200540 }
541 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200542 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200543}
544
545static PyObject*
546faulthandler_is_enabled(PyObject *self)
547{
548 return PyBool_FromLong(fatal_error.enabled);
549}
550
551#ifdef FAULTHANDLER_LATER
552
553static void
554faulthandler_thread(void *unused)
555{
556 PyLockStatus st;
557 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200558 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200559#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200560 sigset_t set;
561
562 /* we don't want to receive any signal */
563 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200564 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200565#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200566
567 do {
568 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200569 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200570 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200571 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200572 break;
573 }
574 /* Timeout => dump traceback */
575 assert(st == PY_LOCK_FAILURE);
576
Victor Stinnerc7489a52015-04-01 18:48:58 +0200577 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200578
Victor Stinner861d9ab2016-03-16 22:45:24 +0100579 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200580 ok = (errmsg == NULL);
581
582 if (thread.exit)
583 _exit(1);
584 } while (ok && thread.repeat);
585
586 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200587 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200588}
589
590static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200591cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200592{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200593 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200594 PyThread_release_lock(thread.cancel_event);
595
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200596 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200597 PyThread_acquire_lock(thread.running, 1);
598 PyThread_release_lock(thread.running);
599
600 /* The main thread should always hold the cancel_event lock */
601 PyThread_acquire_lock(thread.cancel_event, 1);
602
Victor Stinner024e37a2011-03-31 01:31:06 +0200603 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200604 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200605 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200606 thread.header = NULL;
607 }
608}
609
610static char*
611format_timeout(double timeout)
612{
613 unsigned long us, sec, min, hour;
614 double intpart, fracpart;
615 char buffer[100];
616
617 fracpart = modf(timeout, &intpart);
618 sec = (unsigned long)intpart;
619 us = (unsigned long)(fracpart * 1e6);
620 min = sec / 60;
621 sec %= 60;
622 hour = min / 60;
623 min %= 60;
624
625 if (us != 0)
626 PyOS_snprintf(buffer, sizeof(buffer),
627 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
628 hour, min, sec, us);
629 else
630 PyOS_snprintf(buffer, sizeof(buffer),
631 "Timeout (%lu:%02lu:%02lu)!\n",
632 hour, min, sec);
633
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200634 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200635}
636
637static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200638faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200639 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200640{
641 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
642 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200643 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200644 int repeat = 0;
645 PyObject *file = NULL;
646 int fd;
647 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200648 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200649 char *header;
650 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200651
652 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Georg Brandldeb92b52012-09-22 08:58:55 +0200653 "d|iOi:dump_traceback_later", kwlist,
Victor Stinner024e37a2011-03-31 01:31:06 +0200654 &timeout, &repeat, &file, &exit))
655 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200656 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200657 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
658 return NULL;
659 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200660 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200661 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200662 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
663 return NULL;
664 }
665
Victor Stinnera4de6d82011-04-09 00:47:23 +0200666 tstate = get_thread_state();
667 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200668 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200669
Victor Stinner95bb7142015-03-12 15:32:03 +0100670 fd = faulthandler_get_fileno(&file);
671 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200672 return NULL;
673
Victor Stinnerc790a532011-04-08 13:39:59 +0200674 /* format the timeout */
675 header = format_timeout(timeout);
676 if (header == NULL)
677 return PyErr_NoMemory();
678 header_len = strlen(header);
679
Victor Stinner024e37a2011-03-31 01:31:06 +0200680 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200681 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200682
Victor Stinner95bb7142015-03-12 15:32:03 +0100683 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300684 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200685 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200686 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200687 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200688 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200689 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200690 thread.header = header;
691 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200692
693 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200694 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200695
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200696 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200697 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200698 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200699 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200700 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200701 PyErr_SetString(PyExc_RuntimeError,
702 "unable to start watchdog thread");
703 return NULL;
704 }
705
706 Py_RETURN_NONE;
707}
708
709static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200710faulthandler_cancel_dump_traceback_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200711{
Georg Brandldeb92b52012-09-22 08:58:55 +0200712 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200713 Py_RETURN_NONE;
714}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200715#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200716
717#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200718static int
719faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
720{
721#ifdef HAVE_SIGACTION
722 struct sigaction action;
723 action.sa_handler = faulthandler_user;
724 sigemptyset(&action.sa_mask);
725 /* if the signal is received while the kernel is executing a system
726 call, try to restart the system call instead of interrupting it and
727 return EINTR. */
728 action.sa_flags = SA_RESTART;
729 if (chain) {
730 /* do not prevent the signal from being received from within its
731 own signal handler */
732 action.sa_flags = SA_NODEFER;
733 }
734#ifdef HAVE_SIGALTSTACK
735 if (stack.ss_sp != NULL) {
736 /* Call the signal handler on an alternate signal stack
737 provided by sigaltstack() */
738 action.sa_flags |= SA_ONSTACK;
739 }
740#endif
741 return sigaction(signum, &action, p_previous);
742#else
743 _Py_sighandler_t previous;
744 previous = signal(signum, faulthandler_user);
745 if (p_previous != NULL)
746 *p_previous = previous;
747 return (previous == SIG_ERR);
748#endif
749}
750
Victor Stinner024e37a2011-03-31 01:31:06 +0200751/* Handler of user signals (e.g. SIGUSR1).
752
753 Dump the traceback of the current thread, or of all threads if
754 thread.all_threads is true.
755
756 This function is signal safe and should only call signal safe functions. */
757
758static void
759faulthandler_user(int signum)
760{
761 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200762 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200763
764 user = &user_signals[signum];
765 if (!user->enabled)
766 return;
767
Victor Stinnerc7489a52015-04-01 18:48:58 +0200768 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200769
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200770#ifdef HAVE_SIGACTION
771 if (user->chain) {
772 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200773 errno = save_errno;
774
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200775 /* call the previous signal handler */
776 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200777
778 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200779 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200780 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200781 }
782#else
783 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200784 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200785 /* call the previous signal handler */
786 user->previous(signum);
787 }
788#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200789}
790
791static int
792check_signum(int signum)
793{
Victor Stinner46c2b812017-04-21 18:06:13 +0200794 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200795 if (faulthandler_handlers[i].signum == signum) {
796 PyErr_Format(PyExc_RuntimeError,
797 "signal %i cannot be registered, "
798 "use enable() instead",
799 signum);
800 return 0;
801 }
802 }
803 if (signum < 1 || NSIG <= signum) {
804 PyErr_SetString(PyExc_ValueError, "signal number out of range");
805 return 0;
806 }
807 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200808}
809
810static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200811faulthandler_register_py(PyObject *self,
812 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200813{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200814 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200815 int signum;
816 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200817 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200818 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200819 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200820 user_signal_t *user;
821 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200822 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200823 int err;
824
825 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200826 "i|Oii:register", kwlist,
827 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200828 return NULL;
829
Victor Stinner44378d42011-04-01 15:37:12 +0200830 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200831 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200832
Victor Stinnera4de6d82011-04-09 00:47:23 +0200833 tstate = get_thread_state();
834 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200835 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200836
Victor Stinner95bb7142015-03-12 15:32:03 +0100837 fd = faulthandler_get_fileno(&file);
838 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200839 return NULL;
840
841 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200842 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200843 if (user_signals == NULL)
844 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200845 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200846 }
847 user = &user_signals[signum];
848
849 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200850 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200851 if (err) {
852 PyErr_SetFromErrno(PyExc_OSError);
853 return NULL;
854 }
Victor Stinner8d379542013-07-02 00:14:56 +0200855
856 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200857 }
858
Victor Stinner95bb7142015-03-12 15:32:03 +0100859 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300860 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200861 user->fd = fd;
862 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200863 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200864 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200865 user->enabled = 1;
866
867 Py_RETURN_NONE;
868}
869
870static int
871faulthandler_unregister(user_signal_t *user, int signum)
872{
Victor Stinnera01ca122011-04-01 12:56:17 +0200873 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200874 return 0;
875 user->enabled = 0;
876#ifdef HAVE_SIGACTION
877 (void)sigaction(signum, &user->previous, NULL);
878#else
879 (void)signal(signum, user->previous);
880#endif
881 Py_CLEAR(user->file);
882 user->fd = -1;
883 return 1;
884}
885
886static PyObject*
887faulthandler_unregister_py(PyObject *self, PyObject *args)
888{
889 int signum;
890 user_signal_t *user;
891 int change;
892
893 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
894 return NULL;
895
Victor Stinner44378d42011-04-01 15:37:12 +0200896 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200897 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200898
Victor Stinnercfa71232011-04-08 12:48:15 +0200899 if (user_signals == NULL)
900 Py_RETURN_FALSE;
901
Victor Stinner024e37a2011-03-31 01:31:06 +0200902 user = &user_signals[signum];
903 change = faulthandler_unregister(user, signum);
904 return PyBool_FromLong(change);
905}
906#endif /* FAULTHANDLER_USER */
907
908
Victor Stinner7a399122014-09-30 13:40:12 +0200909static void
910faulthandler_suppress_crash_report(void)
911{
912#ifdef MS_WINDOWS
913 UINT mode;
914
915 /* Configure Windows to not display the Windows Error Reporting dialog */
916 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
917 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
918#endif
919
920#ifdef HAVE_SYS_RESOURCE_H
921 struct rlimit rl;
922
923 /* Disable creation of core dump */
924 if (getrlimit(RLIMIT_CORE, &rl) != 0) {
925 rl.rlim_cur = 0;
926 setrlimit(RLIMIT_CORE, &rl);
927 }
928#endif
929
930#ifdef _MSC_VER
931 /* Visual Studio: configure abort() to not display an error message nor
932 open a popup asking to report the fault. */
933 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
934#endif
935}
936
Victor Stinner024e37a2011-03-31 01:31:06 +0200937static PyObject *
938faulthandler_read_null(PyObject *self, PyObject *args)
939{
Victor Stinnera2477202012-01-30 00:07:43 +0100940 volatile int *x;
941 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +0100942
Victor Stinner7a399122014-09-30 13:40:12 +0200943 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +0100944 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +0200945 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +0200946 return PyLong_FromLong(y);
947
948}
949
Victor Stinner50838282014-09-30 13:54:14 +0200950static void
951faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200952{
Victor Stinner7a399122014-09-30 13:40:12 +0200953 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +0200954#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200955 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
956 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200957 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200958 SIGSEGV was raised by the kernel because of a fault, and so if the
959 program retries to execute the same instruction, the fault will be
960 raised again.
961
962 Here the fault is simulated by a fake SIGSEGV signal raised by the
963 application. We have to raise SIGSEGV at lease twice: once for
964 faulthandler_fatal_error(), and one more time for the previous signal
965 handler. */
966 while(1)
967 raise(SIGSEGV);
968#else
969 raise(SIGSEGV);
970#endif
Victor Stinner50838282014-09-30 13:54:14 +0200971}
972
973static PyObject *
974faulthandler_sigsegv(PyObject *self, PyObject *args)
975{
976 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +0100977 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +0200978 return NULL;
979
980 if (release_gil) {
981 Py_BEGIN_ALLOW_THREADS
982 faulthandler_raise_sigsegv();
983 Py_END_ALLOW_THREADS
984 } else {
985 faulthandler_raise_sigsegv();
986 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200987 Py_RETURN_NONE;
988}
989
Victor Stinner861d9ab2016-03-16 22:45:24 +0100990static void
991faulthandler_fatal_error_thread(void *plock)
992{
Victor Stinner9a2329f2016-12-05 17:56:36 +0100993#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +0100994 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +0100995#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +0100996
997 Py_FatalError("in new thread");
998
Victor Stinner9a2329f2016-12-05 17:56:36 +0100999#ifndef __clang__
1000 /* Issue #28152: Py_FatalError() is declared with
1001 __attribute__((__noreturn__)). GCC emits a warning without
1002 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
1003 emits a warning on the return. */
1004
Victor Stinner861d9ab2016-03-16 22:45:24 +01001005 /* notify the caller that we are done */
1006 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +01001007#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001008}
1009
1010static PyObject *
1011faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1012{
1013 long thread;
1014 PyThread_type_lock lock;
1015
1016 faulthandler_suppress_crash_report();
1017
1018 lock = PyThread_allocate_lock();
1019 if (lock == NULL)
1020 return PyErr_NoMemory();
1021
1022 PyThread_acquire_lock(lock, WAIT_LOCK);
1023
1024 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1025 if (thread == -1) {
1026 PyThread_free_lock(lock);
1027 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1028 return NULL;
1029 }
1030
1031 /* wait until the thread completes: it will never occur, since Py_FatalError()
1032 exits the process immedialty. */
1033 PyThread_acquire_lock(lock, WAIT_LOCK);
1034 PyThread_release_lock(lock);
1035 PyThread_free_lock(lock);
1036
1037 Py_RETURN_NONE;
1038}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001039
Victor Stinner024e37a2011-03-31 01:31:06 +02001040static PyObject *
1041faulthandler_sigfpe(PyObject *self, PyObject *args)
1042{
1043 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1044 PowerPC. Use volatile to disable compile-time optimizations. */
1045 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001046 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001047 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001048 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1049 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001050 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001051 /* This line is never reached, but we pretend to make something with z
1052 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001053 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001054}
1055
Victor Stinnerd727e232011-04-01 12:13:55 +02001056static PyObject *
1057faulthandler_sigabrt(PyObject *self, PyObject *args)
1058{
Victor Stinner7a399122014-09-30 13:40:12 +02001059 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001060 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001061 Py_RETURN_NONE;
1062}
1063
Victor Stinner024e37a2011-03-31 01:31:06 +02001064static PyObject *
1065faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1066{
1067 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001068 int release_gil = 0;
1069 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001070 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001071 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001072 if (release_gil) {
1073 Py_BEGIN_ALLOW_THREADS
1074 Py_FatalError(message);
1075 Py_END_ALLOW_THREADS
1076 }
1077 else {
1078 Py_FatalError(message);
1079 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001080 Py_RETURN_NONE;
1081}
1082
1083#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner404cdc52016-03-23 10:39:17 +01001084#define FAULTHANDLER_STACK_OVERFLOW
1085
Victor Stinner19276f12015-03-23 21:20:27 +01001086#ifdef __INTEL_COMPILER
1087 /* Issue #23654: Turn off ICC's tail call optimization for the
1088 * stack_overflow generator. ICC turns the recursive tail call into
1089 * a loop. */
1090# pragma intel optimization_level 0
1091#endif
1092static
Benjamin Petersonca470632016-09-06 13:47:26 -07001093uintptr_t
1094stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001095{
1096 /* allocate 4096 bytes on the stack at each call */
1097 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001098 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001099 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001100 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001101 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001102 buffer[0] = 1;
1103 buffer[4095] = 0;
1104 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001105}
1106
1107static PyObject *
1108faulthandler_stack_overflow(PyObject *self)
1109{
1110 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001111 uintptr_t sp = (uintptr_t)&depth;
1112 uintptr_t stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001113
Victor Stinner7a399122014-09-30 13:40:12 +02001114 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001115 depth = 0;
Victor Stinner928ad282016-03-23 15:19:12 +01001116 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1117 sp + STACK_OVERFLOW_MAX_SIZE,
1118 &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001119 if (sp < stop)
1120 size = stop - sp;
1121 else
1122 size = sp - stop;
1123 PyErr_Format(PyExc_RuntimeError,
1124 "unable to raise a stack overflow (allocated %zu bytes "
1125 "on the stack, %zu recursive calls)",
1126 size, depth);
1127 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001128}
Victor Stinner928ad282016-03-23 15:19:12 +01001129#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001130
1131
1132static int
1133faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1134{
Victor Stinner024e37a2011-03-31 01:31:06 +02001135#ifdef FAULTHANDLER_LATER
1136 Py_VISIT(thread.file);
1137#endif
1138#ifdef FAULTHANDLER_USER
1139 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001140 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001141 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001142 }
1143#endif
1144 Py_VISIT(fatal_error.file);
1145 return 0;
1146}
1147
Victor Stinner404cdc52016-03-23 10:39:17 +01001148#ifdef MS_WINDOWS
1149static PyObject *
1150faulthandler_raise_exception(PyObject *self, PyObject *args)
1151{
1152 unsigned int code, flags = 0;
1153 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1154 return NULL;
1155 faulthandler_suppress_crash_report();
1156 RaiseException(code, flags, 0, NULL);
1157 Py_RETURN_NONE;
1158}
1159#endif
1160
Victor Stinner024e37a2011-03-31 01:31:06 +02001161PyDoc_STRVAR(module_doc,
1162"faulthandler module.");
1163
1164static PyMethodDef module_methods[] = {
1165 {"enable",
Victor Stinner404cdc52016-03-23 10:39:17 +01001166 (PyCFunction)faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001167 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001168 "enable the fault handler")},
1169 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
1170 PyDoc_STR("disable(): disable the fault handler")},
1171 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
1172 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1173 {"dump_traceback",
1174 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001175 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001176 "dump the traceback of the current thread, or of all threads "
1177 "if all_threads is True, into file")},
1178#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001179 {"dump_traceback_later",
1180 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
1181 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001182 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001183 "or each timeout seconds if repeat is True. If exit is True, "
1184 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001185 {"cancel_dump_traceback_later",
1186 (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
1187 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1188 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001189#endif
1190
1191#ifdef FAULTHANDLER_USER
1192 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001193 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1194 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001195 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001196 "traceback of the current thread, or of all threads if "
1197 "all_threads is True, into file")},
1198 {"unregister",
1199 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1200 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1201 "'signum' registered by register()")},
1202#endif
1203
Victor Stinner50838282014-09-30 13:54:14 +02001204 {"_read_null", faulthandler_read_null, METH_NOARGS,
1205 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001206 "a SIGSEGV or SIGBUS signal depending on the platform")},
1207 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001208 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001209 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1210 PyDoc_STR("fatal_error_c_thread(): "
1211 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001212 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001213 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001214 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1215 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001216 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1217 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001218#ifdef FAULTHANDLER_STACK_OVERFLOW
Victor Stinner024e37a2011-03-31 01:31:06 +02001219 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1220 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1221#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001222#ifdef MS_WINDOWS
1223 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1224 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1225#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001226 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001227};
1228
1229static struct PyModuleDef module_def = {
1230 PyModuleDef_HEAD_INIT,
1231 "faulthandler",
1232 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001233 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001234 module_methods,
1235 NULL,
1236 faulthandler_traverse,
1237 NULL,
1238 NULL
1239};
1240
1241PyMODINIT_FUNC
1242PyInit_faulthandler(void)
1243{
Victor Stinner404cdc52016-03-23 10:39:17 +01001244 PyObject *m = PyModule_Create(&module_def);
1245 if (m == NULL)
1246 return NULL;
1247
1248 /* Add constants for unit tests */
1249#ifdef MS_WINDOWS
1250 /* RaiseException() codes (prefixed by an underscore) */
1251 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1252 EXCEPTION_ACCESS_VIOLATION))
1253 return NULL;
1254 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1255 EXCEPTION_INT_DIVIDE_BY_ZERO))
1256 return NULL;
1257 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1258 EXCEPTION_STACK_OVERFLOW))
1259 return NULL;
1260
1261 /* RaiseException() flags (prefixed by an underscore) */
1262 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1263 EXCEPTION_NONCONTINUABLE))
1264 return NULL;
1265 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1266 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1267 return NULL;
1268#endif
1269
1270 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001271}
1272
Victor Stinner410dd7d2011-05-11 20:56:08 +02001273/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1274 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001275
1276static int
1277faulthandler_env_options(void)
1278{
1279 PyObject *xoptions, *key, *module, *res;
Victor Stinner88983502013-09-08 11:36:23 +02001280 char *p;
Victor Stinner024e37a2011-03-31 01:31:06 +02001281
Victor Stinner88983502013-09-08 11:36:23 +02001282 if (!((p = Py_GETENV("PYTHONFAULTHANDLER")) && *p != '\0')) {
1283 /* PYTHONFAULTHANDLER environment variable is missing
1284 or an empty string */
Victor Stinner25095b22011-05-26 13:47:08 +02001285 int has_key;
1286
Victor Stinner024e37a2011-03-31 01:31:06 +02001287 xoptions = PySys_GetXOptions();
1288 if (xoptions == NULL)
1289 return -1;
1290
1291 key = PyUnicode_FromString("faulthandler");
1292 if (key == NULL)
1293 return -1;
1294
Victor Stinner25095b22011-05-26 13:47:08 +02001295 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001296 Py_DECREF(key);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001297 if (has_key <= 0)
1298 return has_key;
Victor Stinner024e37a2011-03-31 01:31:06 +02001299 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001300
1301 module = PyImport_ImportModule("faulthandler");
1302 if (module == NULL) {
1303 return -1;
1304 }
Victor Stinner3466bde2016-09-05 18:16:01 -07001305 res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +02001306 Py_DECREF(module);
1307 if (res == NULL)
1308 return -1;
1309 Py_DECREF(res);
1310 return 0;
1311}
1312
1313int _PyFaulthandler_Init(void)
1314{
1315#ifdef HAVE_SIGALTSTACK
1316 int err;
1317
1318 /* Try to allocate an alternate stack for faulthandler() signal handler to
1319 * be able to allocate memory on the stack, even on a stack overflow. If it
1320 * fails, ignore the error. */
1321 stack.ss_flags = 0;
1322 stack.ss_size = SIGSTKSZ;
1323 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1324 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001325 err = sigaltstack(&stack, &old_stack);
Victor Stinner024e37a2011-03-31 01:31:06 +02001326 if (err) {
1327 PyMem_Free(stack.ss_sp);
1328 stack.ss_sp = NULL;
1329 }
1330 }
1331#endif
1332#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001333 thread.file = NULL;
1334 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001335 thread.running = PyThread_allocate_lock();
1336 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001337 PyErr_SetString(PyExc_RuntimeError,
1338 "could not allocate locks for faulthandler");
1339 return -1;
1340 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001341 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001342#endif
1343
1344 return faulthandler_env_options();
1345}
1346
1347void _PyFaulthandler_Fini(void)
1348{
Victor Stinner024e37a2011-03-31 01:31:06 +02001349#ifdef FAULTHANDLER_LATER
1350 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001351 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001352 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001353 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001354 PyThread_free_lock(thread.cancel_event);
1355 thread.cancel_event = NULL;
1356 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001357 if (thread.running) {
1358 PyThread_free_lock(thread.running);
1359 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001360 }
1361#endif
1362
1363#ifdef FAULTHANDLER_USER
1364 /* user */
1365 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001366 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001367 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001368 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001369 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001370 user_signals = NULL;
1371 }
1372#endif
1373
1374 /* fatal */
1375 faulthandler_disable();
1376#ifdef HAVE_SIGALTSTACK
1377 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001378 /* Fetch the current alt stack */
1379 stack_t current_stack;
1380 if (sigaltstack(NULL, &current_stack) == 0) {
1381 if (current_stack.ss_sp == stack.ss_sp) {
1382 /* The current alt stack is the one that we installed.
1383 It is safe to restore the old stack that we found when
1384 we installed ours */
1385 sigaltstack(&old_stack, NULL);
1386 } else {
1387 /* Someone switched to a different alt stack and didn't
1388 restore ours when they were done (if they're done).
1389 There's not much we can do in this unlikely case */
1390 }
1391 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001392 PyMem_Free(stack.ss_sp);
1393 stack.ss_sp = NULL;
1394 }
1395#endif
1396}