blob: baa2e917706a0351e021dc9989ff17b92b296ebc [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 Stinner8c663fd2017-11-08 14:44:44 -080017/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
18#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
Victor Stinner96994402011-04-07 11:37:19 +020019
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
Victor Stinner93fd4782017-10-27 07:27:12 -0700610#define SEC_TO_US (1000 * 1000)
611
Victor Stinnerc790a532011-04-08 13:39:59 +0200612static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700613format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200614{
Victor Stinner93fd4782017-10-27 07:27:12 -0700615 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200616 char buffer[100];
617
Victor Stinner93fd4782017-10-27 07:27:12 -0700618 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
619 sec = (unsigned long)(us / SEC_TO_US);
620 us %= SEC_TO_US;
621
Victor Stinnerc790a532011-04-08 13:39:59 +0200622 min = sec / 60;
623 sec %= 60;
624 hour = min / 60;
625 min %= 60;
626
Victor Stinner93fd4782017-10-27 07:27:12 -0700627 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200628 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700629 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
630 hour, min, sec, (unsigned int)us);
631 }
632 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200633 PyOS_snprintf(buffer, sizeof(buffer),
634 "Timeout (%lu:%02lu:%02lu)!\n",
635 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700636 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200637 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200638}
639
640static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200641faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200642 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200643{
644 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700645 PyObject *timeout_obj;
646 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200647 int repeat = 0;
648 PyObject *file = NULL;
649 int fd;
650 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200651 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200652 char *header;
653 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200654
655 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700656 "O|iOi:dump_traceback_later", kwlist,
657 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200658 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700659
660 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
661 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200662 return NULL;
663 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700664 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200665 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200666 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
667 return NULL;
668 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700669 /* Limit to LONG_MAX seconds for format_timeout() */
670 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
671 PyErr_SetString(PyExc_OverflowError,
672 "timeout value is too large");
673 return NULL;
674 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200675
Victor Stinnera4de6d82011-04-09 00:47:23 +0200676 tstate = get_thread_state();
677 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200678 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200679
Victor Stinner95bb7142015-03-12 15:32:03 +0100680 fd = faulthandler_get_fileno(&file);
681 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200682 return NULL;
683
Victor Stinnerc790a532011-04-08 13:39:59 +0200684 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700685 header = format_timeout(timeout_us);
Victor Stinnerc790a532011-04-08 13:39:59 +0200686 if (header == NULL)
687 return PyErr_NoMemory();
688 header_len = strlen(header);
689
Victor Stinner024e37a2011-03-31 01:31:06 +0200690 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200691 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200692
Victor Stinner95bb7142015-03-12 15:32:03 +0100693 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300694 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200695 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700696 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
697 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200698 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200699 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200700 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200701 thread.header = header;
702 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200703
704 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200705 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200706
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200707 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200708 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200709 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200710 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200711 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200712 PyErr_SetString(PyExc_RuntimeError,
713 "unable to start watchdog thread");
714 return NULL;
715 }
716
717 Py_RETURN_NONE;
718}
719
720static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200721faulthandler_cancel_dump_traceback_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200722{
Georg Brandldeb92b52012-09-22 08:58:55 +0200723 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200724 Py_RETURN_NONE;
725}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200726#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200727
728#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200729static int
730faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
731{
732#ifdef HAVE_SIGACTION
733 struct sigaction action;
734 action.sa_handler = faulthandler_user;
735 sigemptyset(&action.sa_mask);
736 /* if the signal is received while the kernel is executing a system
737 call, try to restart the system call instead of interrupting it and
738 return EINTR. */
739 action.sa_flags = SA_RESTART;
740 if (chain) {
741 /* do not prevent the signal from being received from within its
742 own signal handler */
743 action.sa_flags = SA_NODEFER;
744 }
745#ifdef HAVE_SIGALTSTACK
746 if (stack.ss_sp != NULL) {
747 /* Call the signal handler on an alternate signal stack
748 provided by sigaltstack() */
749 action.sa_flags |= SA_ONSTACK;
750 }
751#endif
752 return sigaction(signum, &action, p_previous);
753#else
754 _Py_sighandler_t previous;
755 previous = signal(signum, faulthandler_user);
756 if (p_previous != NULL)
757 *p_previous = previous;
758 return (previous == SIG_ERR);
759#endif
760}
761
Victor Stinner024e37a2011-03-31 01:31:06 +0200762/* Handler of user signals (e.g. SIGUSR1).
763
764 Dump the traceback of the current thread, or of all threads if
765 thread.all_threads is true.
766
767 This function is signal safe and should only call signal safe functions. */
768
769static void
770faulthandler_user(int signum)
771{
772 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200773 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200774
775 user = &user_signals[signum];
776 if (!user->enabled)
777 return;
778
Victor Stinnerc7489a52015-04-01 18:48:58 +0200779 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200780
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200781#ifdef HAVE_SIGACTION
782 if (user->chain) {
783 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200784 errno = save_errno;
785
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200786 /* call the previous signal handler */
787 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200788
789 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200790 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200791 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200792 }
793#else
794 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200795 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200796 /* call the previous signal handler */
797 user->previous(signum);
798 }
799#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200800}
801
802static int
803check_signum(int signum)
804{
Victor Stinner46c2b812017-04-21 18:06:13 +0200805 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200806 if (faulthandler_handlers[i].signum == signum) {
807 PyErr_Format(PyExc_RuntimeError,
808 "signal %i cannot be registered, "
809 "use enable() instead",
810 signum);
811 return 0;
812 }
813 }
814 if (signum < 1 || NSIG <= signum) {
815 PyErr_SetString(PyExc_ValueError, "signal number out of range");
816 return 0;
817 }
818 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200819}
820
821static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200822faulthandler_register_py(PyObject *self,
823 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200824{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200825 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200826 int signum;
827 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200828 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200829 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200830 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200831 user_signal_t *user;
832 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200833 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200834 int err;
835
836 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200837 "i|Oii:register", kwlist,
838 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200839 return NULL;
840
Victor Stinner44378d42011-04-01 15:37:12 +0200841 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200842 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200843
Victor Stinnera4de6d82011-04-09 00:47:23 +0200844 tstate = get_thread_state();
845 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200846 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200847
Victor Stinner95bb7142015-03-12 15:32:03 +0100848 fd = faulthandler_get_fileno(&file);
849 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200850 return NULL;
851
852 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200853 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200854 if (user_signals == NULL)
855 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200856 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200857 }
858 user = &user_signals[signum];
859
860 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200861 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200862 if (err) {
863 PyErr_SetFromErrno(PyExc_OSError);
864 return NULL;
865 }
Victor Stinner8d379542013-07-02 00:14:56 +0200866
867 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200868 }
869
Victor Stinner95bb7142015-03-12 15:32:03 +0100870 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300871 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200872 user->fd = fd;
873 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200874 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200875 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200876 user->enabled = 1;
877
878 Py_RETURN_NONE;
879}
880
881static int
882faulthandler_unregister(user_signal_t *user, int signum)
883{
Victor Stinnera01ca122011-04-01 12:56:17 +0200884 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200885 return 0;
886 user->enabled = 0;
887#ifdef HAVE_SIGACTION
888 (void)sigaction(signum, &user->previous, NULL);
889#else
890 (void)signal(signum, user->previous);
891#endif
892 Py_CLEAR(user->file);
893 user->fd = -1;
894 return 1;
895}
896
897static PyObject*
898faulthandler_unregister_py(PyObject *self, PyObject *args)
899{
900 int signum;
901 user_signal_t *user;
902 int change;
903
904 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
905 return NULL;
906
Victor Stinner44378d42011-04-01 15:37:12 +0200907 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200908 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200909
Victor Stinnercfa71232011-04-08 12:48:15 +0200910 if (user_signals == NULL)
911 Py_RETURN_FALSE;
912
Victor Stinner024e37a2011-03-31 01:31:06 +0200913 user = &user_signals[signum];
914 change = faulthandler_unregister(user, signum);
915 return PyBool_FromLong(change);
916}
917#endif /* FAULTHANDLER_USER */
918
919
Victor Stinner7a399122014-09-30 13:40:12 +0200920static void
921faulthandler_suppress_crash_report(void)
922{
923#ifdef MS_WINDOWS
924 UINT mode;
925
926 /* Configure Windows to not display the Windows Error Reporting dialog */
927 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
928 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
929#endif
930
931#ifdef HAVE_SYS_RESOURCE_H
932 struct rlimit rl;
933
934 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +0100935 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +0200936 rl.rlim_cur = 0;
937 setrlimit(RLIMIT_CORE, &rl);
938 }
939#endif
940
941#ifdef _MSC_VER
942 /* Visual Studio: configure abort() to not display an error message nor
943 open a popup asking to report the fault. */
944 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
945#endif
946}
947
Victor Stinner024e37a2011-03-31 01:31:06 +0200948static PyObject *
949faulthandler_read_null(PyObject *self, PyObject *args)
950{
Victor Stinnera2477202012-01-30 00:07:43 +0100951 volatile int *x;
952 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +0100953
Victor Stinner7a399122014-09-30 13:40:12 +0200954 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +0100955 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +0200956 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +0200957 return PyLong_FromLong(y);
958
959}
960
Victor Stinner50838282014-09-30 13:54:14 +0200961static void
962faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200963{
Victor Stinner7a399122014-09-30 13:40:12 +0200964 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +0200965#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200966 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
967 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200968 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200969 SIGSEGV was raised by the kernel because of a fault, and so if the
970 program retries to execute the same instruction, the fault will be
971 raised again.
972
973 Here the fault is simulated by a fake SIGSEGV signal raised by the
974 application. We have to raise SIGSEGV at lease twice: once for
975 faulthandler_fatal_error(), and one more time for the previous signal
976 handler. */
977 while(1)
978 raise(SIGSEGV);
979#else
980 raise(SIGSEGV);
981#endif
Victor Stinner50838282014-09-30 13:54:14 +0200982}
983
984static PyObject *
985faulthandler_sigsegv(PyObject *self, PyObject *args)
986{
987 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +0100988 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +0200989 return NULL;
990
991 if (release_gil) {
992 Py_BEGIN_ALLOW_THREADS
993 faulthandler_raise_sigsegv();
994 Py_END_ALLOW_THREADS
995 } else {
996 faulthandler_raise_sigsegv();
997 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200998 Py_RETURN_NONE;
999}
1000
Victor Stinner861d9ab2016-03-16 22:45:24 +01001001static void
1002faulthandler_fatal_error_thread(void *plock)
1003{
Victor Stinner9a2329f2016-12-05 17:56:36 +01001004#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +01001005 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +01001006#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001007
1008 Py_FatalError("in new thread");
1009
Victor Stinner9a2329f2016-12-05 17:56:36 +01001010#ifndef __clang__
1011 /* Issue #28152: Py_FatalError() is declared with
1012 __attribute__((__noreturn__)). GCC emits a warning without
1013 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
1014 emits a warning on the return. */
1015
Victor Stinner861d9ab2016-03-16 22:45:24 +01001016 /* notify the caller that we are done */
1017 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +01001018#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001019}
1020
1021static PyObject *
1022faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1023{
1024 long thread;
1025 PyThread_type_lock lock;
1026
1027 faulthandler_suppress_crash_report();
1028
1029 lock = PyThread_allocate_lock();
1030 if (lock == NULL)
1031 return PyErr_NoMemory();
1032
1033 PyThread_acquire_lock(lock, WAIT_LOCK);
1034
1035 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1036 if (thread == -1) {
1037 PyThread_free_lock(lock);
1038 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1039 return NULL;
1040 }
1041
1042 /* wait until the thread completes: it will never occur, since Py_FatalError()
1043 exits the process immedialty. */
1044 PyThread_acquire_lock(lock, WAIT_LOCK);
1045 PyThread_release_lock(lock);
1046 PyThread_free_lock(lock);
1047
1048 Py_RETURN_NONE;
1049}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001050
Victor Stinner024e37a2011-03-31 01:31:06 +02001051static PyObject *
1052faulthandler_sigfpe(PyObject *self, PyObject *args)
1053{
1054 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1055 PowerPC. Use volatile to disable compile-time optimizations. */
1056 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001057 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001058 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001059 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1060 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001061 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001062 /* This line is never reached, but we pretend to make something with z
1063 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001064 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001065}
1066
Victor Stinnerd727e232011-04-01 12:13:55 +02001067static PyObject *
1068faulthandler_sigabrt(PyObject *self, PyObject *args)
1069{
Victor Stinner7a399122014-09-30 13:40:12 +02001070 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001071 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001072 Py_RETURN_NONE;
1073}
1074
Victor Stinner024e37a2011-03-31 01:31:06 +02001075static PyObject *
1076faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1077{
1078 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001079 int release_gil = 0;
1080 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001081 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001082 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001083 if (release_gil) {
1084 Py_BEGIN_ALLOW_THREADS
1085 Py_FatalError(message);
1086 Py_END_ALLOW_THREADS
1087 }
1088 else {
1089 Py_FatalError(message);
1090 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001091 Py_RETURN_NONE;
1092}
1093
1094#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner404cdc52016-03-23 10:39:17 +01001095#define FAULTHANDLER_STACK_OVERFLOW
1096
Victor Stinner19276f12015-03-23 21:20:27 +01001097#ifdef __INTEL_COMPILER
1098 /* Issue #23654: Turn off ICC's tail call optimization for the
1099 * stack_overflow generator. ICC turns the recursive tail call into
1100 * a loop. */
1101# pragma intel optimization_level 0
1102#endif
1103static
Benjamin Petersonca470632016-09-06 13:47:26 -07001104uintptr_t
1105stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001106{
1107 /* allocate 4096 bytes on the stack at each call */
1108 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001109 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001110 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001111 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001112 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001113 buffer[0] = 1;
1114 buffer[4095] = 0;
1115 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001116}
1117
1118static PyObject *
1119faulthandler_stack_overflow(PyObject *self)
1120{
1121 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001122 uintptr_t sp = (uintptr_t)&depth;
1123 uintptr_t stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001124
Victor Stinner7a399122014-09-30 13:40:12 +02001125 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001126 depth = 0;
Victor Stinner928ad282016-03-23 15:19:12 +01001127 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1128 sp + STACK_OVERFLOW_MAX_SIZE,
1129 &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001130 if (sp < stop)
1131 size = stop - sp;
1132 else
1133 size = sp - stop;
1134 PyErr_Format(PyExc_RuntimeError,
1135 "unable to raise a stack overflow (allocated %zu bytes "
1136 "on the stack, %zu recursive calls)",
1137 size, depth);
1138 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001139}
Victor Stinner928ad282016-03-23 15:19:12 +01001140#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001141
1142
1143static int
1144faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1145{
Victor Stinner024e37a2011-03-31 01:31:06 +02001146#ifdef FAULTHANDLER_LATER
1147 Py_VISIT(thread.file);
1148#endif
1149#ifdef FAULTHANDLER_USER
1150 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001151 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001152 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001153 }
1154#endif
1155 Py_VISIT(fatal_error.file);
1156 return 0;
1157}
1158
Victor Stinner404cdc52016-03-23 10:39:17 +01001159#ifdef MS_WINDOWS
1160static PyObject *
1161faulthandler_raise_exception(PyObject *self, PyObject *args)
1162{
1163 unsigned int code, flags = 0;
1164 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1165 return NULL;
1166 faulthandler_suppress_crash_report();
1167 RaiseException(code, flags, 0, NULL);
1168 Py_RETURN_NONE;
1169}
1170#endif
1171
Victor Stinner024e37a2011-03-31 01:31:06 +02001172PyDoc_STRVAR(module_doc,
1173"faulthandler module.");
1174
1175static PyMethodDef module_methods[] = {
1176 {"enable",
Victor Stinner404cdc52016-03-23 10:39:17 +01001177 (PyCFunction)faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001178 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001179 "enable the fault handler")},
1180 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
1181 PyDoc_STR("disable(): disable the fault handler")},
1182 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
1183 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1184 {"dump_traceback",
1185 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001186 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001187 "dump the traceback of the current thread, or of all threads "
1188 "if all_threads is True, into file")},
1189#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001190 {"dump_traceback_later",
1191 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
1192 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001193 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001194 "or each timeout seconds if repeat is True. If exit is True, "
1195 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001196 {"cancel_dump_traceback_later",
1197 (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
1198 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1199 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001200#endif
1201
1202#ifdef FAULTHANDLER_USER
1203 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001204 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1205 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001206 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001207 "traceback of the current thread, or of all threads if "
1208 "all_threads is True, into file")},
1209 {"unregister",
1210 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1211 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1212 "'signum' registered by register()")},
1213#endif
1214
Victor Stinner50838282014-09-30 13:54:14 +02001215 {"_read_null", faulthandler_read_null, METH_NOARGS,
1216 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001217 "a SIGSEGV or SIGBUS signal depending on the platform")},
1218 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001219 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001220 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1221 PyDoc_STR("fatal_error_c_thread(): "
1222 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001223 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001224 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001225 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1226 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001227 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1228 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001229#ifdef FAULTHANDLER_STACK_OVERFLOW
Victor Stinner024e37a2011-03-31 01:31:06 +02001230 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1231 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1232#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001233#ifdef MS_WINDOWS
1234 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1235 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1236#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001237 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001238};
1239
1240static struct PyModuleDef module_def = {
1241 PyModuleDef_HEAD_INIT,
1242 "faulthandler",
1243 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001244 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001245 module_methods,
1246 NULL,
1247 faulthandler_traverse,
1248 NULL,
1249 NULL
1250};
1251
1252PyMODINIT_FUNC
1253PyInit_faulthandler(void)
1254{
Victor Stinner404cdc52016-03-23 10:39:17 +01001255 PyObject *m = PyModule_Create(&module_def);
1256 if (m == NULL)
1257 return NULL;
1258
1259 /* Add constants for unit tests */
1260#ifdef MS_WINDOWS
1261 /* RaiseException() codes (prefixed by an underscore) */
1262 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1263 EXCEPTION_ACCESS_VIOLATION))
1264 return NULL;
1265 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1266 EXCEPTION_INT_DIVIDE_BY_ZERO))
1267 return NULL;
1268 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1269 EXCEPTION_STACK_OVERFLOW))
1270 return NULL;
1271
1272 /* RaiseException() flags (prefixed by an underscore) */
1273 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1274 EXCEPTION_NONCONTINUABLE))
1275 return NULL;
1276 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1277 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1278 return NULL;
1279#endif
1280
1281 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001282}
1283
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001284static int
1285faulthandler_init_enable(void)
1286{
1287 PyObject *module = PyImport_ImportModule("faulthandler");
1288 if (module == NULL) {
1289 return -1;
1290 }
1291
1292 PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
1293 Py_DECREF(module);
1294 if (res == NULL) {
1295 return -1;
1296 }
1297 Py_DECREF(res);
1298
1299 return 0;
1300}
1301
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001302_PyInitError
Victor Stinnera7368ac2017-11-15 18:11:45 -08001303_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001304{
1305#ifdef HAVE_SIGALTSTACK
1306 int err;
1307
1308 /* Try to allocate an alternate stack for faulthandler() signal handler to
1309 * be able to allocate memory on the stack, even on a stack overflow. If it
1310 * fails, ignore the error. */
1311 stack.ss_flags = 0;
1312 stack.ss_size = SIGSTKSZ;
1313 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1314 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001315 err = sigaltstack(&stack, &old_stack);
Victor Stinner024e37a2011-03-31 01:31:06 +02001316 if (err) {
1317 PyMem_Free(stack.ss_sp);
1318 stack.ss_sp = NULL;
1319 }
1320 }
1321#endif
1322#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001323 thread.file = NULL;
1324 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001325 thread.running = PyThread_allocate_lock();
1326 if (!thread.cancel_event || !thread.running) {
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001327 return _Py_INIT_ERR("failed to allocate locks for faulthandler");
Victor Stinner024e37a2011-03-31 01:31:06 +02001328 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001329 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001330#endif
1331
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001332 if (enable) {
1333 if (faulthandler_init_enable() < 0) {
1334 return _Py_INIT_ERR("failed to enable faulthandler");
1335 }
1336 }
1337 return _Py_INIT_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001338}
1339
1340void _PyFaulthandler_Fini(void)
1341{
Victor Stinner024e37a2011-03-31 01:31:06 +02001342#ifdef FAULTHANDLER_LATER
1343 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001344 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001345 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001346 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001347 PyThread_free_lock(thread.cancel_event);
1348 thread.cancel_event = NULL;
1349 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001350 if (thread.running) {
1351 PyThread_free_lock(thread.running);
1352 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001353 }
1354#endif
1355
1356#ifdef FAULTHANDLER_USER
1357 /* user */
1358 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001359 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001360 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001361 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001362 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001363 user_signals = NULL;
1364 }
1365#endif
1366
1367 /* fatal */
1368 faulthandler_disable();
1369#ifdef HAVE_SIGALTSTACK
1370 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001371 /* Fetch the current alt stack */
1372 stack_t current_stack;
1373 if (sigaltstack(NULL, &current_stack) == 0) {
1374 if (current_stack.ss_sp == stack.ss_sp) {
1375 /* The current alt stack is the one that we installed.
1376 It is safe to restore the old stack that we found when
1377 we installed ours */
1378 sigaltstack(&old_stack, NULL);
1379 } else {
1380 /* Someone switched to a different alt stack and didn't
1381 restore ours when they were done (if they're done).
1382 There's not much we can do in this unlikely case */
1383 }
1384 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001385 PyMem_Free(stack.ss_sp);
1386 stack.ss_sp = NULL;
1387 }
1388#endif
1389}