blob: 2f9c2f675836b805c4d349a71c24befcc7ec4dfd [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*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530536faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200537{
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*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530546faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200547{
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*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530721faulthandler_cancel_dump_traceback_later_py(PyObject *self,
722 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200723{
Georg Brandldeb92b52012-09-22 08:58:55 +0200724 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200725 Py_RETURN_NONE;
726}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200727#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200728
729#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200730static int
731faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
732{
733#ifdef HAVE_SIGACTION
734 struct sigaction action;
735 action.sa_handler = faulthandler_user;
736 sigemptyset(&action.sa_mask);
737 /* if the signal is received while the kernel is executing a system
738 call, try to restart the system call instead of interrupting it and
739 return EINTR. */
740 action.sa_flags = SA_RESTART;
741 if (chain) {
742 /* do not prevent the signal from being received from within its
743 own signal handler */
744 action.sa_flags = SA_NODEFER;
745 }
746#ifdef HAVE_SIGALTSTACK
747 if (stack.ss_sp != NULL) {
748 /* Call the signal handler on an alternate signal stack
749 provided by sigaltstack() */
750 action.sa_flags |= SA_ONSTACK;
751 }
752#endif
753 return sigaction(signum, &action, p_previous);
754#else
755 _Py_sighandler_t previous;
756 previous = signal(signum, faulthandler_user);
757 if (p_previous != NULL)
758 *p_previous = previous;
759 return (previous == SIG_ERR);
760#endif
761}
762
Victor Stinner024e37a2011-03-31 01:31:06 +0200763/* Handler of user signals (e.g. SIGUSR1).
764
765 Dump the traceback of the current thread, or of all threads if
766 thread.all_threads is true.
767
768 This function is signal safe and should only call signal safe functions. */
769
770static void
771faulthandler_user(int signum)
772{
773 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200774 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200775
776 user = &user_signals[signum];
777 if (!user->enabled)
778 return;
779
Victor Stinnerc7489a52015-04-01 18:48:58 +0200780 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200781
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200782#ifdef HAVE_SIGACTION
783 if (user->chain) {
784 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200785 errno = save_errno;
786
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200787 /* call the previous signal handler */
788 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200789
790 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200791 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200792 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200793 }
794#else
795 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200796 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200797 /* call the previous signal handler */
798 user->previous(signum);
799 }
800#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200801}
802
803static int
804check_signum(int signum)
805{
Victor Stinner46c2b812017-04-21 18:06:13 +0200806 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200807 if (faulthandler_handlers[i].signum == signum) {
808 PyErr_Format(PyExc_RuntimeError,
809 "signal %i cannot be registered, "
810 "use enable() instead",
811 signum);
812 return 0;
813 }
814 }
815 if (signum < 1 || NSIG <= signum) {
816 PyErr_SetString(PyExc_ValueError, "signal number out of range");
817 return 0;
818 }
819 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200820}
821
822static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200823faulthandler_register_py(PyObject *self,
824 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200825{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200826 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200827 int signum;
828 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200829 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200830 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200831 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200832 user_signal_t *user;
833 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200834 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200835 int err;
836
837 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200838 "i|Oii:register", kwlist,
839 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200840 return NULL;
841
Victor Stinner44378d42011-04-01 15:37:12 +0200842 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200843 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200844
Victor Stinnera4de6d82011-04-09 00:47:23 +0200845 tstate = get_thread_state();
846 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200847 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200848
Victor Stinner95bb7142015-03-12 15:32:03 +0100849 fd = faulthandler_get_fileno(&file);
850 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200851 return NULL;
852
853 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200854 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200855 if (user_signals == NULL)
856 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200857 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200858 }
859 user = &user_signals[signum];
860
861 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200862 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200863 if (err) {
864 PyErr_SetFromErrno(PyExc_OSError);
865 return NULL;
866 }
Victor Stinner8d379542013-07-02 00:14:56 +0200867
868 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200869 }
870
Victor Stinner95bb7142015-03-12 15:32:03 +0100871 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300872 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200873 user->fd = fd;
874 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200875 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200876 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200877 user->enabled = 1;
878
879 Py_RETURN_NONE;
880}
881
882static int
883faulthandler_unregister(user_signal_t *user, int signum)
884{
Victor Stinnera01ca122011-04-01 12:56:17 +0200885 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200886 return 0;
887 user->enabled = 0;
888#ifdef HAVE_SIGACTION
889 (void)sigaction(signum, &user->previous, NULL);
890#else
891 (void)signal(signum, user->previous);
892#endif
893 Py_CLEAR(user->file);
894 user->fd = -1;
895 return 1;
896}
897
898static PyObject*
899faulthandler_unregister_py(PyObject *self, PyObject *args)
900{
901 int signum;
902 user_signal_t *user;
903 int change;
904
905 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
906 return NULL;
907
Victor Stinner44378d42011-04-01 15:37:12 +0200908 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200909 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200910
Victor Stinnercfa71232011-04-08 12:48:15 +0200911 if (user_signals == NULL)
912 Py_RETURN_FALSE;
913
Victor Stinner024e37a2011-03-31 01:31:06 +0200914 user = &user_signals[signum];
915 change = faulthandler_unregister(user, signum);
916 return PyBool_FromLong(change);
917}
918#endif /* FAULTHANDLER_USER */
919
920
Victor Stinner7a399122014-09-30 13:40:12 +0200921static void
922faulthandler_suppress_crash_report(void)
923{
924#ifdef MS_WINDOWS
925 UINT mode;
926
927 /* Configure Windows to not display the Windows Error Reporting dialog */
928 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
929 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
930#endif
931
932#ifdef HAVE_SYS_RESOURCE_H
933 struct rlimit rl;
934
935 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +0100936 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +0200937 rl.rlim_cur = 0;
938 setrlimit(RLIMIT_CORE, &rl);
939 }
940#endif
941
942#ifdef _MSC_VER
943 /* Visual Studio: configure abort() to not display an error message nor
944 open a popup asking to report the fault. */
945 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
946#endif
947}
948
Victor Stinner024e37a2011-03-31 01:31:06 +0200949static PyObject *
950faulthandler_read_null(PyObject *self, PyObject *args)
951{
Victor Stinnera2477202012-01-30 00:07:43 +0100952 volatile int *x;
953 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +0100954
Victor Stinner7a399122014-09-30 13:40:12 +0200955 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +0100956 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +0200957 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +0200958 return PyLong_FromLong(y);
959
960}
961
Victor Stinner50838282014-09-30 13:54:14 +0200962static void
963faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200964{
Victor Stinner7a399122014-09-30 13:40:12 +0200965 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +0200966#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200967 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
968 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200969 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200970 SIGSEGV was raised by the kernel because of a fault, and so if the
971 program retries to execute the same instruction, the fault will be
972 raised again.
973
974 Here the fault is simulated by a fake SIGSEGV signal raised by the
975 application. We have to raise SIGSEGV at lease twice: once for
976 faulthandler_fatal_error(), and one more time for the previous signal
977 handler. */
978 while(1)
979 raise(SIGSEGV);
980#else
981 raise(SIGSEGV);
982#endif
Victor Stinner50838282014-09-30 13:54:14 +0200983}
984
985static PyObject *
986faulthandler_sigsegv(PyObject *self, PyObject *args)
987{
988 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +0100989 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +0200990 return NULL;
991
992 if (release_gil) {
993 Py_BEGIN_ALLOW_THREADS
994 faulthandler_raise_sigsegv();
995 Py_END_ALLOW_THREADS
996 } else {
997 faulthandler_raise_sigsegv();
998 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200999 Py_RETURN_NONE;
1000}
1001
Victor Stinner861d9ab2016-03-16 22:45:24 +01001002static void
1003faulthandler_fatal_error_thread(void *plock)
1004{
Victor Stinner9a2329f2016-12-05 17:56:36 +01001005#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +01001006 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +01001007#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001008
1009 Py_FatalError("in new thread");
1010
Victor Stinner9a2329f2016-12-05 17:56:36 +01001011#ifndef __clang__
1012 /* Issue #28152: Py_FatalError() is declared with
1013 __attribute__((__noreturn__)). GCC emits a warning without
1014 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
1015 emits a warning on the return. */
1016
Victor Stinner861d9ab2016-03-16 22:45:24 +01001017 /* notify the caller that we are done */
1018 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +01001019#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001020}
1021
1022static PyObject *
1023faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1024{
1025 long thread;
1026 PyThread_type_lock lock;
1027
1028 faulthandler_suppress_crash_report();
1029
1030 lock = PyThread_allocate_lock();
1031 if (lock == NULL)
1032 return PyErr_NoMemory();
1033
1034 PyThread_acquire_lock(lock, WAIT_LOCK);
1035
1036 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1037 if (thread == -1) {
1038 PyThread_free_lock(lock);
1039 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1040 return NULL;
1041 }
1042
1043 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001044 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001045 PyThread_acquire_lock(lock, WAIT_LOCK);
1046 PyThread_release_lock(lock);
1047 PyThread_free_lock(lock);
1048
1049 Py_RETURN_NONE;
1050}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001051
Victor Stinner024e37a2011-03-31 01:31:06 +02001052static PyObject *
1053faulthandler_sigfpe(PyObject *self, PyObject *args)
1054{
1055 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1056 PowerPC. Use volatile to disable compile-time optimizations. */
1057 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001058 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001059 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001060 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1061 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001062 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001063 /* This line is never reached, but we pretend to make something with z
1064 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001065 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001066}
1067
Victor Stinnerd727e232011-04-01 12:13:55 +02001068static PyObject *
1069faulthandler_sigabrt(PyObject *self, PyObject *args)
1070{
Victor Stinner7a399122014-09-30 13:40:12 +02001071 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001072 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001073 Py_RETURN_NONE;
1074}
1075
Victor Stinner024e37a2011-03-31 01:31:06 +02001076static PyObject *
1077faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1078{
1079 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001080 int release_gil = 0;
1081 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001082 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001083 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001084 if (release_gil) {
1085 Py_BEGIN_ALLOW_THREADS
1086 Py_FatalError(message);
1087 Py_END_ALLOW_THREADS
1088 }
1089 else {
1090 Py_FatalError(message);
1091 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001092 Py_RETURN_NONE;
1093}
1094
1095#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner404cdc52016-03-23 10:39:17 +01001096#define FAULTHANDLER_STACK_OVERFLOW
1097
Victor Stinner19276f12015-03-23 21:20:27 +01001098#ifdef __INTEL_COMPILER
1099 /* Issue #23654: Turn off ICC's tail call optimization for the
1100 * stack_overflow generator. ICC turns the recursive tail call into
1101 * a loop. */
1102# pragma intel optimization_level 0
1103#endif
1104static
Benjamin Petersonca470632016-09-06 13:47:26 -07001105uintptr_t
1106stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001107{
1108 /* allocate 4096 bytes on the stack at each call */
1109 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001110 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001111 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001112 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001113 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001114 buffer[0] = 1;
1115 buffer[4095] = 0;
1116 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001117}
1118
1119static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301120faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001121{
1122 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001123 uintptr_t sp = (uintptr_t)&depth;
1124 uintptr_t stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001125
Victor Stinner7a399122014-09-30 13:40:12 +02001126 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001127 depth = 0;
Victor Stinner928ad282016-03-23 15:19:12 +01001128 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1129 sp + STACK_OVERFLOW_MAX_SIZE,
1130 &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001131 if (sp < stop)
1132 size = stop - sp;
1133 else
1134 size = sp - stop;
1135 PyErr_Format(PyExc_RuntimeError,
1136 "unable to raise a stack overflow (allocated %zu bytes "
1137 "on the stack, %zu recursive calls)",
1138 size, depth);
1139 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001140}
Victor Stinner928ad282016-03-23 15:19:12 +01001141#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001142
1143
1144static int
1145faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1146{
Victor Stinner024e37a2011-03-31 01:31:06 +02001147#ifdef FAULTHANDLER_LATER
1148 Py_VISIT(thread.file);
1149#endif
1150#ifdef FAULTHANDLER_USER
1151 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001152 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001153 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001154 }
1155#endif
1156 Py_VISIT(fatal_error.file);
1157 return 0;
1158}
1159
Victor Stinner404cdc52016-03-23 10:39:17 +01001160#ifdef MS_WINDOWS
1161static PyObject *
1162faulthandler_raise_exception(PyObject *self, PyObject *args)
1163{
1164 unsigned int code, flags = 0;
1165 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1166 return NULL;
1167 faulthandler_suppress_crash_report();
1168 RaiseException(code, flags, 0, NULL);
1169 Py_RETURN_NONE;
1170}
1171#endif
1172
Victor Stinner024e37a2011-03-31 01:31:06 +02001173PyDoc_STRVAR(module_doc,
1174"faulthandler module.");
1175
1176static PyMethodDef module_methods[] = {
1177 {"enable",
Victor Stinner404cdc52016-03-23 10:39:17 +01001178 (PyCFunction)faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001179 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001180 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301181 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001182 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301183 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001184 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1185 {"dump_traceback",
1186 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001187 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001188 "dump the traceback of the current thread, or of all threads "
1189 "if all_threads is True, into file")},
1190#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001191 {"dump_traceback_later",
1192 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
1193 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001194 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001195 "or each timeout seconds if repeat is True. If exit is True, "
1196 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001197 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301198 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001199 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1200 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001201#endif
1202
1203#ifdef FAULTHANDLER_USER
1204 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001205 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1206 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001207 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001208 "traceback of the current thread, or of all threads if "
1209 "all_threads is True, into file")},
1210 {"unregister",
1211 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1212 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1213 "'signum' registered by register()")},
1214#endif
1215
Victor Stinner50838282014-09-30 13:54:14 +02001216 {"_read_null", faulthandler_read_null, METH_NOARGS,
1217 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001218 "a SIGSEGV or SIGBUS signal depending on the platform")},
1219 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001220 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001221 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1222 PyDoc_STR("fatal_error_c_thread(): "
1223 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001224 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001225 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001226 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1227 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001228 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1229 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001230#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301231 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001232 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1233#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001234#ifdef MS_WINDOWS
1235 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1236 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1237#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001238 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001239};
1240
1241static struct PyModuleDef module_def = {
1242 PyModuleDef_HEAD_INIT,
1243 "faulthandler",
1244 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001245 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001246 module_methods,
1247 NULL,
1248 faulthandler_traverse,
1249 NULL,
1250 NULL
1251};
1252
1253PyMODINIT_FUNC
1254PyInit_faulthandler(void)
1255{
Victor Stinner404cdc52016-03-23 10:39:17 +01001256 PyObject *m = PyModule_Create(&module_def);
1257 if (m == NULL)
1258 return NULL;
1259
1260 /* Add constants for unit tests */
1261#ifdef MS_WINDOWS
1262 /* RaiseException() codes (prefixed by an underscore) */
1263 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1264 EXCEPTION_ACCESS_VIOLATION))
1265 return NULL;
1266 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1267 EXCEPTION_INT_DIVIDE_BY_ZERO))
1268 return NULL;
1269 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1270 EXCEPTION_STACK_OVERFLOW))
1271 return NULL;
1272
1273 /* RaiseException() flags (prefixed by an underscore) */
1274 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1275 EXCEPTION_NONCONTINUABLE))
1276 return NULL;
1277 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1278 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1279 return NULL;
1280#endif
1281
1282 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001283}
1284
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001285static int
1286faulthandler_init_enable(void)
1287{
1288 PyObject *module = PyImport_ImportModule("faulthandler");
1289 if (module == NULL) {
1290 return -1;
1291 }
1292
1293 PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
1294 Py_DECREF(module);
1295 if (res == NULL) {
1296 return -1;
1297 }
1298 Py_DECREF(res);
1299
1300 return 0;
1301}
1302
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001303_PyInitError
Victor Stinnera7368ac2017-11-15 18:11:45 -08001304_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001305{
1306#ifdef HAVE_SIGALTSTACK
1307 int err;
1308
1309 /* Try to allocate an alternate stack for faulthandler() signal handler to
1310 * be able to allocate memory on the stack, even on a stack overflow. If it
1311 * fails, ignore the error. */
1312 stack.ss_flags = 0;
1313 stack.ss_size = SIGSTKSZ;
1314 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1315 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001316 err = sigaltstack(&stack, &old_stack);
Victor Stinner024e37a2011-03-31 01:31:06 +02001317 if (err) {
1318 PyMem_Free(stack.ss_sp);
1319 stack.ss_sp = NULL;
1320 }
1321 }
1322#endif
1323#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001324 thread.file = NULL;
1325 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001326 thread.running = PyThread_allocate_lock();
1327 if (!thread.cancel_event || !thread.running) {
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001328 return _Py_INIT_ERR("failed to allocate locks for faulthandler");
Victor Stinner024e37a2011-03-31 01:31:06 +02001329 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001330 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001331#endif
1332
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001333 if (enable) {
1334 if (faulthandler_init_enable() < 0) {
1335 return _Py_INIT_ERR("failed to enable faulthandler");
1336 }
1337 }
1338 return _Py_INIT_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001339}
1340
1341void _PyFaulthandler_Fini(void)
1342{
Victor Stinner024e37a2011-03-31 01:31:06 +02001343#ifdef FAULTHANDLER_LATER
1344 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001345 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001346 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001347 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001348 PyThread_free_lock(thread.cancel_event);
1349 thread.cancel_event = NULL;
1350 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001351 if (thread.running) {
1352 PyThread_free_lock(thread.running);
1353 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001354 }
1355#endif
1356
1357#ifdef FAULTHANDLER_USER
1358 /* user */
1359 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001360 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001361 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001362 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001363 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001364 user_signals = NULL;
1365 }
1366#endif
1367
1368 /* fatal */
1369 faulthandler_disable();
1370#ifdef HAVE_SIGALTSTACK
1371 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001372 /* Fetch the current alt stack */
1373 stack_t current_stack;
1374 if (sigaltstack(NULL, &current_stack) == 0) {
1375 if (current_stack.ss_sp == stack.ss_sp) {
1376 /* The current alt stack is the one that we installed.
1377 It is safe to restore the old stack that we found when
1378 we installed ours */
1379 sigaltstack(&old_stack, NULL);
1380 } else {
1381 /* Someone switched to a different alt stack and didn't
1382 restore ours when they were done (if they're done).
1383 There's not much we can do in this unlikely case */
1384 }
1385 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001386 PyMem_Free(stack.ss_sp);
1387 stack.ss_sp = NULL;
1388 }
1389#endif
1390}