blob: 555e1afc9f82a63e565a78d782dc8e5b9baa4b9d [file] [log] [blame]
Victor Stinner024e37a2011-03-31 01:31:06 +02001#include "Python.h"
Victor Stinner331a6a52019-05-27 16:39:22 +02002#include "pycore_initconfig.h"
Victor Stinnered488662019-05-20 00:14:57 +02003#include "pycore_traceback.h"
Victor Stinner024e37a2011-03-31 01:31:06 +02004#include "pythread.h"
5#include <signal.h>
6#include <object.h>
7#include <frameobject.h>
8#include <signal.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +02009#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinner7a399122014-09-30 13:40:12 +020010# include <pthread.h>
11#endif
12#ifdef MS_WINDOWS
13# include <windows.h>
14#endif
15#ifdef HAVE_SYS_RESOURCE_H
16# include <sys/resource.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +020017#endif
18
Victor Stinner8c663fd2017-11-08 14:44:44 -080019/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
20#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
Victor Stinner96994402011-04-07 11:37:19 +020021
Victor Stinner024e37a2011-03-31 01:31:06 +020022#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
Victor Stinner024e37a2011-03-31 01:31:06 +020061static struct {
62 PyObject *file;
63 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020064 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020065 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020066 PyInterpreterState *interp;
67 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020068 char *header;
69 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020070 /* The main thread always holds this lock. It is only released when
71 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020072 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020073 PyThread_type_lock cancel_event;
74 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020075 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020076} thread;
Victor Stinner024e37a2011-03-31 01:31:06 +020077
78#ifdef FAULTHANDLER_USER
79typedef struct {
80 int enabled;
81 PyObject *file;
82 int fd;
83 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020084 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020085 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020086 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020087} user_signal_t;
88
89static user_signal_t *user_signals;
90
91/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +020092#ifndef NSIG
93# if defined(_NSIG)
94# define NSIG _NSIG /* For BSD/SysV */
95# elif defined(_SIGMAX)
96# define NSIG (_SIGMAX + 1) /* For QNX */
97# elif defined(SIGMAX)
98# define NSIG (SIGMAX + 1) /* For djgpp */
99# else
100# define NSIG 64 /* Use a reasonable default value */
101# endif
102#endif
103
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200104static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200105#endif /* FAULTHANDLER_USER */
106
107
108static fault_handler_t faulthandler_handlers[] = {
109#ifdef SIGBUS
110 {SIGBUS, 0, "Bus error", },
111#endif
112#ifdef SIGILL
113 {SIGILL, 0, "Illegal instruction", },
114#endif
115 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200116 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200117 /* define SIGSEGV at the end to make it the default choice if searching the
118 handler fails in faulthandler_fatal_error() */
119 {SIGSEGV, 0, "Segmentation fault", }
120};
Victor Stinner404cdc52016-03-23 10:39:17 +0100121static const size_t faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200122 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200123
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100124/* Using an alternative stack requires sigaltstack()
125 and sigaction() SA_ONSTACK */
126#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
127# define FAULTHANDLER_USE_ALT_STACK
128#endif
129
130#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +0200131static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700132static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200133#endif
134
135
136/* Get the file descriptor of a file by calling its fileno() method and then
137 call its flush() method.
138
139 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100140 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200141
Victor Stinner95bb7142015-03-12 15:32:03 +0100142 On success, return the file descriptor and write the new file into *file_ptr.
143 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200144
Victor Stinner95bb7142015-03-12 15:32:03 +0100145static int
146faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200147{
148 PyObject *result;
149 long fd_long;
150 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100151 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200152
153 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100154 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200155 if (file == NULL) {
156 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100157 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200158 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200159 if (file == Py_None) {
160 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100161 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200162 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200163 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100164 else if (PyLong_Check(file)) {
165 fd = _PyLong_AsInt(file);
166 if (fd == -1 && PyErr_Occurred())
167 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700168 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100169 PyErr_SetString(PyExc_ValueError,
170 "file is not a valid file descripter");
171 return -1;
172 }
173 *file_ptr = NULL;
174 return fd;
175 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200176
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200177 result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno);
Victor Stinner024e37a2011-03-31 01:31:06 +0200178 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100179 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200180
181 fd = -1;
182 if (PyLong_Check(result)) {
183 fd_long = PyLong_AsLong(result);
184 if (0 <= fd_long && fd_long < INT_MAX)
185 fd = (int)fd_long;
186 }
187 Py_DECREF(result);
188
189 if (fd == -1) {
190 PyErr_SetString(PyExc_RuntimeError,
191 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100192 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200193 }
194
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200195 result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200196 if (result != NULL)
197 Py_DECREF(result);
198 else {
199 /* ignore flush() error */
200 PyErr_Clear();
201 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100202 *file_ptr = file;
203 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200204}
205
Victor Stinnera4de6d82011-04-09 00:47:23 +0200206/* Get the state of the current thread: only call this function if the current
207 thread holds the GIL. Raise an exception on error. */
208static PyThreadState*
209get_thread_state(void)
210{
Victor Stinner861d9ab2016-03-16 22:45:24 +0100211 PyThreadState *tstate = _PyThreadState_UncheckedGet();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200212 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100213 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200214 PyErr_SetString(PyExc_RuntimeError,
215 "unable to get the current thread state");
216 return NULL;
217 }
218 return tstate;
219}
220
Victor Stinnerc7489a52015-04-01 18:48:58 +0200221static void
222faulthandler_dump_traceback(int fd, int all_threads,
223 PyInterpreterState *interp)
224{
225 static volatile int reentrant = 0;
226 PyThreadState *tstate;
227
228 if (reentrant)
229 return;
230
231 reentrant = 1;
232
Victor Stinnerc7489a52015-04-01 18:48:58 +0200233 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
234 are thus delivered to the thread that caused the fault. Get the Python
235 thread state of the current thread.
236
237 PyThreadState_Get() doesn't give the state of the thread that caused the
238 fault if the thread released the GIL, and so this function cannot be
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900239 used. Read the thread specific storage (TSS) instead: call
Victor Stinnerc7489a52015-04-01 18:48:58 +0200240 PyGILState_GetThisThreadState(). */
241 tstate = PyGILState_GetThisThreadState();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200242
Victor Stinner861d9ab2016-03-16 22:45:24 +0100243 if (all_threads) {
244 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
245 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200246 else {
247 if (tstate != NULL)
248 _Py_DumpTraceback(fd, tstate);
249 }
250
251 reentrant = 0;
252}
253
Victor Stinner024e37a2011-03-31 01:31:06 +0200254static PyObject*
255faulthandler_dump_traceback_py(PyObject *self,
256 PyObject *args, PyObject *kwargs)
257{
258 static char *kwlist[] = {"file", "all_threads", NULL};
259 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200260 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200261 PyThreadState *tstate;
262 const char *errmsg;
263 int fd;
264
265 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
266 "|Oi:dump_traceback", kwlist,
267 &file, &all_threads))
268 return NULL;
269
Victor Stinner95bb7142015-03-12 15:32:03 +0100270 fd = faulthandler_get_fileno(&file);
271 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200272 return NULL;
273
Victor Stinnera4de6d82011-04-09 00:47:23 +0200274 tstate = get_thread_state();
275 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200276 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200277
278 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100279 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200280 if (errmsg != NULL) {
281 PyErr_SetString(PyExc_RuntimeError, errmsg);
282 return NULL;
283 }
284 }
285 else {
286 _Py_DumpTraceback(fd, tstate);
287 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200288
289 if (PyErr_CheckSignals())
290 return NULL;
291
Victor Stinner024e37a2011-03-31 01:31:06 +0200292 Py_RETURN_NONE;
293}
294
Victor Stinner404cdc52016-03-23 10:39:17 +0100295static void
296faulthandler_disable_fatal_handler(fault_handler_t *handler)
297{
298 if (!handler->enabled)
299 return;
300 handler->enabled = 0;
301#ifdef HAVE_SIGACTION
302 (void)sigaction(handler->signum, &handler->previous, NULL);
303#else
304 (void)signal(handler->signum, handler->previous);
305#endif
306}
307
Victor Stinner024e37a2011-03-31 01:31:06 +0200308
Victor Stinner410dd7d2011-05-11 20:56:08 +0200309/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200310
311 Display the current Python traceback, restore the previous handler and call
312 the previous handler.
313
Victor Stinner410dd7d2011-05-11 20:56:08 +0200314 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200315 signal handler would not be called (for an unknown reason). The execution of
316 the program continues at faulthandler_fatal_error() exit, but the same
317 instruction will raise the same fault (signal), and so the previous handler
318 will be called.
319
Victor Stinner410dd7d2011-05-11 20:56:08 +0200320 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200321
322static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200323faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200324{
325 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100326 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200327 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200328 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200329
330 if (!fatal_error.enabled)
331 return;
332
333 for (i=0; i < faulthandler_nsignals; i++) {
334 handler = &faulthandler_handlers[i];
335 if (handler->signum == signum)
336 break;
337 }
338 if (handler == NULL) {
339 /* faulthandler_nsignals == 0 (unlikely) */
340 return;
341 }
342
343 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100344 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200345
346 PUTS(fd, "Fatal Python error: ");
347 PUTS(fd, handler->name);
348 PUTS(fd, "\n\n");
349
Victor Stinnerc7489a52015-04-01 18:48:58 +0200350 faulthandler_dump_traceback(fd, fatal_error.all_threads,
351 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200352
Victor Stinnerc9256172011-05-07 12:20:11 +0200353 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200354#ifdef MS_WINDOWS
355 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200356 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200357 handler, because the Windows signal handler would not be called */
358 return;
359 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200360#endif
R David Murrayfc069992013-12-13 20:52:19 -0500361 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200362 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
363 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200364}
365
Victor Stinner404cdc52016-03-23 10:39:17 +0100366#ifdef MS_WINDOWS
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700367static int
368faulthandler_ignore_exception(DWORD code)
369{
370 /* bpo-30557: ignore exceptions which are not errors */
371 if (!(code & 0x80000000)) {
372 return 1;
373 }
374 /* bpo-31701: ignore MSC and COM exceptions
375 E0000000 + code */
376 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
377 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
378 return 1;
379 }
380 /* Interesting exception: log it with the Python traceback */
381 return 0;
382}
383
Victor Stinner404cdc52016-03-23 10:39:17 +0100384static LONG WINAPI
385faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
386{
387 const int fd = fatal_error.fd;
388 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100389 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100390
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700391 if (faulthandler_ignore_exception(code)) {
392 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100393 return EXCEPTION_CONTINUE_SEARCH;
394 }
395
396 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100397 switch (code)
398 {
399 /* only format most common errors */
400 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
401 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
402 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
403 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
404 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
405 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
406 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
407 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700408 PUTS(fd, "code 0x");
409 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100410 }
411 PUTS(fd, "\n\n");
412
413 if (code == EXCEPTION_ACCESS_VIOLATION) {
414 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200415 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100416 fault_handler_t *handler = &faulthandler_handlers[i];
417 if (handler->signum == SIGSEGV) {
418 faulthandler_disable_fatal_handler(handler);
419 break;
420 }
421 }
422 }
423
424 faulthandler_dump_traceback(fd, fatal_error.all_threads,
425 fatal_error.interp);
426
427 /* call the next exception handler */
428 return EXCEPTION_CONTINUE_SEARCH;
429}
430#endif
431
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100432
433#ifdef FAULTHANDLER_USE_ALT_STACK
434static int
435faulthandler_allocate_stack(void)
436{
437 if (stack.ss_sp != NULL) {
438 return 0;
439 }
440 /* Allocate an alternate stack for faulthandler() signal handler
441 to be able to execute a signal handler on a stack overflow error */
442 stack.ss_sp = PyMem_Malloc(stack.ss_size);
443 if (stack.ss_sp == NULL) {
444 PyErr_NoMemory();
445 return -1;
446 }
447
448 int err = sigaltstack(&stack, &old_stack);
449 if (err) {
450 /* Release the stack to retry sigaltstack() next time */
451 PyMem_Free(stack.ss_sp);
452 stack.ss_sp = NULL;
453
454 PyErr_SetFromErrno(PyExc_OSError);
455 return -1;
456 }
457 return 0;
458}
459#endif
460
461
Victor Stinnerd727e232011-04-01 12:13:55 +0200462/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200463
doko@ubuntu.combc731502016-05-18 01:06:01 +0200464static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100465faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200466{
Victor Stinner404cdc52016-03-23 10:39:17 +0100467 if (fatal_error.enabled) {
468 return 0;
469 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100470 fatal_error.enabled = 1;
471
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100472#ifdef FAULTHANDLER_USE_ALT_STACK
473 if (faulthandler_allocate_stack() < 0) {
474 return -1;
475 }
476#endif
477
Victor Stinner46c2b812017-04-21 18:06:13 +0200478 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100479 fault_handler_t *handler;
Victor Stinner928ad282016-03-23 15:19:12 +0100480 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100481
Victor Stinner928ad282016-03-23 15:19:12 +0100482 handler = &faulthandler_handlers[i];
483 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100484#ifdef HAVE_SIGACTION
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100485 struct sigaction action;
Victor Stinner404cdc52016-03-23 10:39:17 +0100486 action.sa_handler = faulthandler_fatal_error;
487 sigemptyset(&action.sa_mask);
488 /* Do not prevent the signal from being received from within
489 its own signal handler */
490 action.sa_flags = SA_NODEFER;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100491#ifdef FAULTHANDLER_USE_ALT_STACK
492 assert(stack.ss_sp != NULL);
493 /* Call the signal handler on an alternate signal stack
494 provided by sigaltstack() */
495 action.sa_flags |= SA_ONSTACK;
Victor Stinner404cdc52016-03-23 10:39:17 +0100496#endif
497 err = sigaction(handler->signum, &action, &handler->previous);
498#else
499 handler->previous = signal(handler->signum,
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100500 faulthandler_fatal_error);
Victor Stinner404cdc52016-03-23 10:39:17 +0100501 err = (handler->previous == SIG_ERR);
502#endif
503 if (err) {
504 PyErr_SetFromErrno(PyExc_RuntimeError);
505 return -1;
506 }
507
508 handler->enabled = 1;
509 }
510
511#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200512 assert(fatal_error.exc_handler == NULL);
513 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100514#endif
515 return 0;
516}
517
518static PyObject*
519faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
520{
521 static char *kwlist[] = {"file", "all_threads", NULL};
522 PyObject *file = NULL;
523 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200524 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200525 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200526
527 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
528 "|Oi:enable", kwlist, &file, &all_threads))
529 return NULL;
530
Victor Stinner95bb7142015-03-12 15:32:03 +0100531 fd = faulthandler_get_fileno(&file);
532 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200533 return NULL;
534
Victor Stinnera4de6d82011-04-09 00:47:23 +0200535 tstate = get_thread_state();
536 if (tstate == NULL)
537 return NULL;
538
Victor Stinner95bb7142015-03-12 15:32:03 +0100539 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300540 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200541 fatal_error.fd = fd;
542 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200543 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200544
Victor Stinner404cdc52016-03-23 10:39:17 +0100545 if (faulthandler_enable() < 0) {
546 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200547 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100548
Victor Stinner024e37a2011-03-31 01:31:06 +0200549 Py_RETURN_NONE;
550}
551
552static void
553faulthandler_disable(void)
554{
Victor Stinner024e37a2011-03-31 01:31:06 +0200555 if (fatal_error.enabled) {
556 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200557 for (size_t i=0; i < faulthandler_nsignals; i++) {
558 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200559 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100560 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200561 }
562 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200563#ifdef MS_WINDOWS
564 if (fatal_error.exc_handler != NULL) {
565 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
566 fatal_error.exc_handler = NULL;
567 }
568#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200569 Py_CLEAR(fatal_error.file);
570}
571
572static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530573faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200574{
575 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200576 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200577 }
578 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200579 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200580}
581
582static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530583faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200584{
585 return PyBool_FromLong(fatal_error.enabled);
586}
587
Victor Stinner024e37a2011-03-31 01:31:06 +0200588static void
589faulthandler_thread(void *unused)
590{
591 PyLockStatus st;
592 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200593 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200594#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200595 sigset_t set;
596
597 /* we don't want to receive any signal */
598 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200599 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200600#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200601
602 do {
603 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200604 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200605 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200606 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200607 break;
608 }
609 /* Timeout => dump traceback */
610 assert(st == PY_LOCK_FAILURE);
611
Victor Stinnerc7489a52015-04-01 18:48:58 +0200612 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200613
Victor Stinner861d9ab2016-03-16 22:45:24 +0100614 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200615 ok = (errmsg == NULL);
616
617 if (thread.exit)
618 _exit(1);
619 } while (ok && thread.repeat);
620
621 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200622 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200623}
624
625static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200626cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200627{
Thomas A Caswelle2783352019-08-29 12:30:04 -0400628 /* If not scheduled, nothing to cancel */
629 if (!thread.cancel_event) {
630 return;
631 }
632
Victor Stinner410dd7d2011-05-11 20:56:08 +0200633 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200634 PyThread_release_lock(thread.cancel_event);
635
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200636 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200637 PyThread_acquire_lock(thread.running, 1);
638 PyThread_release_lock(thread.running);
639
640 /* The main thread should always hold the cancel_event lock */
641 PyThread_acquire_lock(thread.cancel_event, 1);
642
Victor Stinner024e37a2011-03-31 01:31:06 +0200643 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200644 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200645 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200646 thread.header = NULL;
647 }
648}
649
Victor Stinner93fd4782017-10-27 07:27:12 -0700650#define SEC_TO_US (1000 * 1000)
651
Victor Stinnerc790a532011-04-08 13:39:59 +0200652static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700653format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200654{
Victor Stinner93fd4782017-10-27 07:27:12 -0700655 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200656 char buffer[100];
657
Victor Stinner93fd4782017-10-27 07:27:12 -0700658 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
659 sec = (unsigned long)(us / SEC_TO_US);
660 us %= SEC_TO_US;
661
Victor Stinnerc790a532011-04-08 13:39:59 +0200662 min = sec / 60;
663 sec %= 60;
664 hour = min / 60;
665 min %= 60;
666
Victor Stinner93fd4782017-10-27 07:27:12 -0700667 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200668 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700669 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
670 hour, min, sec, (unsigned int)us);
671 }
672 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200673 PyOS_snprintf(buffer, sizeof(buffer),
674 "Timeout (%lu:%02lu:%02lu)!\n",
675 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700676 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200677 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200678}
679
680static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200681faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200682 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200683{
684 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700685 PyObject *timeout_obj;
686 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200687 int repeat = 0;
688 PyObject *file = NULL;
689 int fd;
690 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200691 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200692 char *header;
693 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200694
695 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700696 "O|iOi:dump_traceback_later", kwlist,
697 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200698 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700699
700 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
701 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200702 return NULL;
703 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700704 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200705 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200706 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
707 return NULL;
708 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700709 /* Limit to LONG_MAX seconds for format_timeout() */
710 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
711 PyErr_SetString(PyExc_OverflowError,
712 "timeout value is too large");
713 return NULL;
714 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200715
Victor Stinnera4de6d82011-04-09 00:47:23 +0200716 tstate = get_thread_state();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100717 if (tstate == NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200718 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100719 }
Victor Stinner96994402011-04-07 11:37:19 +0200720
Victor Stinner95bb7142015-03-12 15:32:03 +0100721 fd = faulthandler_get_fileno(&file);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100722 if (fd < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200723 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100724 }
725
726 if (!thread.running) {
727 thread.running = PyThread_allocate_lock();
728 if (!thread.running) {
729 return PyErr_NoMemory();
730 }
731 }
732 if (!thread.cancel_event) {
733 thread.cancel_event = PyThread_allocate_lock();
734 if (!thread.cancel_event || !thread.running) {
735 return PyErr_NoMemory();
736 }
737
738 /* cancel_event starts to be acquired: it's only released to cancel
739 the thread. */
740 PyThread_acquire_lock(thread.cancel_event, 1);
741 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200742
Victor Stinnerc790a532011-04-08 13:39:59 +0200743 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700744 header = format_timeout(timeout_us);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100745 if (header == NULL) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200746 return PyErr_NoMemory();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100747 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200748 header_len = strlen(header);
749
Victor Stinner024e37a2011-03-31 01:31:06 +0200750 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200751 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200752
Victor Stinner95bb7142015-03-12 15:32:03 +0100753 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300754 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200755 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700756 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
757 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200758 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200759 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200760 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200761 thread.header = header;
762 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200763
764 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200765 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200766
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200767 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200768 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200769 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200770 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200771 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200772 PyErr_SetString(PyExc_RuntimeError,
773 "unable to start watchdog thread");
774 return NULL;
775 }
776
777 Py_RETURN_NONE;
778}
779
780static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530781faulthandler_cancel_dump_traceback_later_py(PyObject *self,
782 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200783{
Georg Brandldeb92b52012-09-22 08:58:55 +0200784 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200785 Py_RETURN_NONE;
786}
Victor Stinner024e37a2011-03-31 01:31:06 +0200787
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100788
Victor Stinner024e37a2011-03-31 01:31:06 +0200789#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200790static int
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100791faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200792{
793#ifdef HAVE_SIGACTION
794 struct sigaction action;
795 action.sa_handler = faulthandler_user;
796 sigemptyset(&action.sa_mask);
797 /* if the signal is received while the kernel is executing a system
798 call, try to restart the system call instead of interrupting it and
799 return EINTR. */
800 action.sa_flags = SA_RESTART;
801 if (chain) {
802 /* do not prevent the signal from being received from within its
803 own signal handler */
804 action.sa_flags = SA_NODEFER;
805 }
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100806#ifdef FAULTHANDLER_USE_ALT_STACK
807 assert(stack.ss_sp != NULL);
808 /* Call the signal handler on an alternate signal stack
809 provided by sigaltstack() */
810 action.sa_flags |= SA_ONSTACK;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200811#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100812 return sigaction(signum, &action, previous_p);
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200813#else
814 _Py_sighandler_t previous;
815 previous = signal(signum, faulthandler_user);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100816 if (previous_p != NULL) {
817 *previous_p = previous;
818 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200819 return (previous == SIG_ERR);
820#endif
821}
822
Victor Stinner024e37a2011-03-31 01:31:06 +0200823/* Handler of user signals (e.g. SIGUSR1).
824
825 Dump the traceback of the current thread, or of all threads if
826 thread.all_threads is true.
827
828 This function is signal safe and should only call signal safe functions. */
829
830static void
831faulthandler_user(int signum)
832{
833 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200834 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200835
836 user = &user_signals[signum];
837 if (!user->enabled)
838 return;
839
Victor Stinnerc7489a52015-04-01 18:48:58 +0200840 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200841
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200842#ifdef HAVE_SIGACTION
843 if (user->chain) {
844 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200845 errno = save_errno;
846
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200847 /* call the previous signal handler */
848 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200849
850 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200851 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200852 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200853 }
854#else
855 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200856 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200857 /* call the previous signal handler */
858 user->previous(signum);
859 }
860#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200861}
862
863static int
864check_signum(int signum)
865{
Victor Stinner46c2b812017-04-21 18:06:13 +0200866 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200867 if (faulthandler_handlers[i].signum == signum) {
868 PyErr_Format(PyExc_RuntimeError,
869 "signal %i cannot be registered, "
870 "use enable() instead",
871 signum);
872 return 0;
873 }
874 }
875 if (signum < 1 || NSIG <= signum) {
876 PyErr_SetString(PyExc_ValueError, "signal number out of range");
877 return 0;
878 }
879 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200880}
881
882static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200883faulthandler_register_py(PyObject *self,
884 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200885{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200886 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200887 int signum;
888 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200889 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200890 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200891 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200892 user_signal_t *user;
893 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200894 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200895 int err;
896
897 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200898 "i|Oii:register", kwlist,
899 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200900 return NULL;
901
Victor Stinner44378d42011-04-01 15:37:12 +0200902 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200903 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200904
Victor Stinnera4de6d82011-04-09 00:47:23 +0200905 tstate = get_thread_state();
906 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200907 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200908
Victor Stinner95bb7142015-03-12 15:32:03 +0100909 fd = faulthandler_get_fileno(&file);
910 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200911 return NULL;
912
913 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200914 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200915 if (user_signals == NULL)
916 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200917 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200918 }
919 user = &user_signals[signum];
920
921 if (!user->enabled) {
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100922#ifdef FAULTHANDLER_USE_ALT_STACK
923 if (faulthandler_allocate_stack() < 0) {
924 return NULL;
925 }
926#endif
927
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200928 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200929 if (err) {
930 PyErr_SetFromErrno(PyExc_OSError);
931 return NULL;
932 }
Victor Stinner8d379542013-07-02 00:14:56 +0200933
934 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200935 }
936
Victor Stinner95bb7142015-03-12 15:32:03 +0100937 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300938 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200939 user->fd = fd;
940 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200941 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200942 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200943 user->enabled = 1;
944
945 Py_RETURN_NONE;
946}
947
948static int
949faulthandler_unregister(user_signal_t *user, int signum)
950{
Victor Stinnera01ca122011-04-01 12:56:17 +0200951 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200952 return 0;
953 user->enabled = 0;
954#ifdef HAVE_SIGACTION
955 (void)sigaction(signum, &user->previous, NULL);
956#else
957 (void)signal(signum, user->previous);
958#endif
959 Py_CLEAR(user->file);
960 user->fd = -1;
961 return 1;
962}
963
964static PyObject*
965faulthandler_unregister_py(PyObject *self, PyObject *args)
966{
967 int signum;
968 user_signal_t *user;
969 int change;
970
971 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
972 return NULL;
973
Victor Stinner44378d42011-04-01 15:37:12 +0200974 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200975 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200976
Victor Stinnercfa71232011-04-08 12:48:15 +0200977 if (user_signals == NULL)
978 Py_RETURN_FALSE;
979
Victor Stinner024e37a2011-03-31 01:31:06 +0200980 user = &user_signals[signum];
981 change = faulthandler_unregister(user, signum);
982 return PyBool_FromLong(change);
983}
984#endif /* FAULTHANDLER_USER */
985
986
Victor Stinner7a399122014-09-30 13:40:12 +0200987static void
988faulthandler_suppress_crash_report(void)
989{
990#ifdef MS_WINDOWS
991 UINT mode;
992
993 /* Configure Windows to not display the Windows Error Reporting dialog */
994 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
995 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
996#endif
997
998#ifdef HAVE_SYS_RESOURCE_H
999 struct rlimit rl;
1000
1001 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +01001002 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +02001003 rl.rlim_cur = 0;
1004 setrlimit(RLIMIT_CORE, &rl);
1005 }
1006#endif
1007
1008#ifdef _MSC_VER
1009 /* Visual Studio: configure abort() to not display an error message nor
1010 open a popup asking to report the fault. */
1011 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1012#endif
1013}
1014
Victor Stinner024e37a2011-03-31 01:31:06 +02001015static PyObject *
1016faulthandler_read_null(PyObject *self, PyObject *args)
1017{
Victor Stinnera2477202012-01-30 00:07:43 +01001018 volatile int *x;
1019 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +01001020
Victor Stinner7a399122014-09-30 13:40:12 +02001021 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +01001022 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +02001023 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +02001024 return PyLong_FromLong(y);
1025
1026}
1027
Victor Stinner50838282014-09-30 13:54:14 +02001028static void
1029faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +02001030{
Victor Stinner7a399122014-09-30 13:40:12 +02001031 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001032#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +02001033 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
1034 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +02001035 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +02001036 SIGSEGV was raised by the kernel because of a fault, and so if the
1037 program retries to execute the same instruction, the fault will be
1038 raised again.
1039
1040 Here the fault is simulated by a fake SIGSEGV signal raised by the
1041 application. We have to raise SIGSEGV at lease twice: once for
1042 faulthandler_fatal_error(), and one more time for the previous signal
1043 handler. */
1044 while(1)
1045 raise(SIGSEGV);
1046#else
1047 raise(SIGSEGV);
1048#endif
Victor Stinner50838282014-09-30 13:54:14 +02001049}
1050
1051static PyObject *
1052faulthandler_sigsegv(PyObject *self, PyObject *args)
1053{
1054 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +01001055 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +02001056 return NULL;
1057
1058 if (release_gil) {
1059 Py_BEGIN_ALLOW_THREADS
1060 faulthandler_raise_sigsegv();
1061 Py_END_ALLOW_THREADS
1062 } else {
1063 faulthandler_raise_sigsegv();
1064 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001065 Py_RETURN_NONE;
1066}
1067
Victor Stinner2a4903f2020-01-30 13:09:11 +01001068static void _Py_NO_RETURN
Victor Stinner861d9ab2016-03-16 22:45:24 +01001069faulthandler_fatal_error_thread(void *plock)
1070{
Victor Stinner861d9ab2016-03-16 22:45:24 +01001071 Py_FatalError("in new thread");
Victor Stinner861d9ab2016-03-16 22:45:24 +01001072}
1073
1074static PyObject *
1075faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1076{
1077 long thread;
1078 PyThread_type_lock lock;
1079
1080 faulthandler_suppress_crash_report();
1081
1082 lock = PyThread_allocate_lock();
1083 if (lock == NULL)
1084 return PyErr_NoMemory();
1085
1086 PyThread_acquire_lock(lock, WAIT_LOCK);
1087
1088 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1089 if (thread == -1) {
1090 PyThread_free_lock(lock);
1091 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1092 return NULL;
1093 }
1094
1095 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001096 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001097 PyThread_acquire_lock(lock, WAIT_LOCK);
1098 PyThread_release_lock(lock);
1099 PyThread_free_lock(lock);
1100
1101 Py_RETURN_NONE;
1102}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001103
Victor Stinner024e37a2011-03-31 01:31:06 +02001104static PyObject *
1105faulthandler_sigfpe(PyObject *self, PyObject *args)
1106{
1107 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1108 PowerPC. Use volatile to disable compile-time optimizations. */
1109 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001110 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001111 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001112 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1113 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001114 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001115 /* This line is never reached, but we pretend to make something with z
1116 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001117 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001118}
1119
Victor Stinnerd727e232011-04-01 12:13:55 +02001120static PyObject *
1121faulthandler_sigabrt(PyObject *self, PyObject *args)
1122{
Victor Stinner7a399122014-09-30 13:40:12 +02001123 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001124 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001125 Py_RETURN_NONE;
1126}
1127
Victor Stinner024e37a2011-03-31 01:31:06 +02001128static PyObject *
1129faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1130{
1131 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001132 int release_gil = 0;
1133 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001134 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001135 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001136 if (release_gil) {
1137 Py_BEGIN_ALLOW_THREADS
1138 Py_FatalError(message);
1139 Py_END_ALLOW_THREADS
1140 }
1141 else {
1142 Py_FatalError(message);
1143 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001144 Py_RETURN_NONE;
1145}
1146
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001147#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001148#define FAULTHANDLER_STACK_OVERFLOW
1149
Victor Stinner8b787962019-12-04 21:10:06 +01001150static uintptr_t
Benjamin Petersonca470632016-09-06 13:47:26 -07001151stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001152{
Victor Stinner8b787962019-12-04 21:10:06 +01001153 /* Allocate (at least) 4096 bytes on the stack at each call.
1154
1155 bpo-23654, bpo-38965: use volatile keyword to prevent tail call
1156 optimization. */
1157 volatile unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001158 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001159 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001160 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001161 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001162 buffer[0] = 1;
1163 buffer[4095] = 0;
1164 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001165}
1166
1167static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301168faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001169{
1170 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001171 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001172 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001173
Victor Stinner7a399122014-09-30 13:40:12 +02001174 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001175 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001176
1177 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1178 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1179 }
1180 else {
1181 lower_limit = 0;
1182 }
1183
1184 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1185 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1186 }
1187 else {
1188 upper_limit = UINTPTR_MAX;
1189 }
1190
1191 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001192 if (sp < stop)
1193 size = stop - sp;
1194 else
1195 size = sp - stop;
1196 PyErr_Format(PyExc_RuntimeError,
1197 "unable to raise a stack overflow (allocated %zu bytes "
1198 "on the stack, %zu recursive calls)",
1199 size, depth);
1200 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001201}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001202#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001203
1204
1205static int
1206faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1207{
Victor Stinner024e37a2011-03-31 01:31:06 +02001208 Py_VISIT(thread.file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001209#ifdef FAULTHANDLER_USER
1210 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001211 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001212 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001213 }
1214#endif
1215 Py_VISIT(fatal_error.file);
1216 return 0;
1217}
1218
Victor Stinner404cdc52016-03-23 10:39:17 +01001219#ifdef MS_WINDOWS
1220static PyObject *
1221faulthandler_raise_exception(PyObject *self, PyObject *args)
1222{
1223 unsigned int code, flags = 0;
1224 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1225 return NULL;
1226 faulthandler_suppress_crash_report();
1227 RaiseException(code, flags, 0, NULL);
1228 Py_RETURN_NONE;
1229}
1230#endif
1231
Victor Stinner024e37a2011-03-31 01:31:06 +02001232PyDoc_STRVAR(module_doc,
1233"faulthandler module.");
1234
1235static PyMethodDef module_methods[] = {
1236 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001237 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001238 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001239 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301240 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001241 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301242 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001243 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1244 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001245 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001246 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001247 "dump the traceback of the current thread, or of all threads "
1248 "if all_threads is True, into file")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001249 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001250 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001251 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001252 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001253 "or each timeout seconds if repeat is True. If exit is True, "
1254 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001255 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301256 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001257 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1258 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001259#ifdef FAULTHANDLER_USER
1260 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001261 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001262 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001263 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001264 "traceback of the current thread, or of all threads if "
1265 "all_threads is True, into file")},
1266 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001267 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001268 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1269 "'signum' registered by register()")},
1270#endif
Victor Stinner50838282014-09-30 13:54:14 +02001271 {"_read_null", faulthandler_read_null, METH_NOARGS,
1272 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001273 "a SIGSEGV or SIGBUS signal depending on the platform")},
1274 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001275 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001276 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1277 PyDoc_STR("fatal_error_c_thread(): "
1278 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001279 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001280 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001281 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1282 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001283 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1284 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001285#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301286 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001287 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1288#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001289#ifdef MS_WINDOWS
1290 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1291 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1292#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001293 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001294};
1295
1296static struct PyModuleDef module_def = {
1297 PyModuleDef_HEAD_INIT,
1298 "faulthandler",
1299 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001300 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001301 module_methods,
1302 NULL,
1303 faulthandler_traverse,
1304 NULL,
1305 NULL
1306};
1307
1308PyMODINIT_FUNC
1309PyInit_faulthandler(void)
1310{
Victor Stinner404cdc52016-03-23 10:39:17 +01001311 PyObject *m = PyModule_Create(&module_def);
1312 if (m == NULL)
1313 return NULL;
1314
1315 /* Add constants for unit tests */
1316#ifdef MS_WINDOWS
1317 /* RaiseException() codes (prefixed by an underscore) */
1318 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
Brandt Bucherac223542019-11-19 15:13:05 -08001319 EXCEPTION_ACCESS_VIOLATION)) {
1320 goto error;
1321 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001322 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
Brandt Bucherac223542019-11-19 15:13:05 -08001323 EXCEPTION_INT_DIVIDE_BY_ZERO)) {
1324 goto error;
1325 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001326 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
Brandt Bucherac223542019-11-19 15:13:05 -08001327 EXCEPTION_STACK_OVERFLOW)) {
1328 goto error;
1329 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001330
1331 /* RaiseException() flags (prefixed by an underscore) */
1332 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
Brandt Bucherac223542019-11-19 15:13:05 -08001333 EXCEPTION_NONCONTINUABLE)) {
1334 goto error;
1335 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001336 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
Brandt Bucherac223542019-11-19 15:13:05 -08001337 EXCEPTION_NONCONTINUABLE_EXCEPTION)) {
1338 goto error;
1339 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001340#endif
1341
1342 return m;
Brandt Bucherac223542019-11-19 15:13:05 -08001343
1344#ifdef MS_WINDOWS
1345error:
1346 Py_DECREF(m);
1347 return NULL;
1348#endif
Victor Stinner024e37a2011-03-31 01:31:06 +02001349}
1350
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001351static int
1352faulthandler_init_enable(void)
1353{
1354 PyObject *module = PyImport_ImportModule("faulthandler");
1355 if (module == NULL) {
1356 return -1;
1357 }
1358
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001359 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001360 Py_DECREF(module);
1361 if (res == NULL) {
1362 return -1;
1363 }
1364 Py_DECREF(res);
1365
1366 return 0;
1367}
1368
Victor Stinner331a6a52019-05-27 16:39:22 +02001369PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001370_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001371{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001372#ifdef FAULTHANDLER_USE_ALT_STACK
1373 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001374 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001375 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1376 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1377 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1378 platforms. */
1379 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001380#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001381
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001382 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001383
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001384 if (enable) {
1385 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001386 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001387 }
1388 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001389 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001390}
1391
1392void _PyFaulthandler_Fini(void)
1393{
Victor Stinner024e37a2011-03-31 01:31:06 +02001394 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001395 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001396 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001397 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001398 PyThread_free_lock(thread.cancel_event);
1399 thread.cancel_event = NULL;
1400 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001401 if (thread.running) {
1402 PyThread_free_lock(thread.running);
1403 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001404 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001405
1406#ifdef FAULTHANDLER_USER
1407 /* user */
1408 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001409 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001410 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001411 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001412 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001413 user_signals = NULL;
1414 }
1415#endif
1416
1417 /* fatal */
1418 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001419
1420#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001421 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001422 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001423 stack_t current_stack;
1424 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001425 if (sigaltstack(NULL, &current_stack) == 0) {
1426 if (current_stack.ss_sp == stack.ss_sp) {
1427 /* The current alt stack is the one that we installed.
1428 It is safe to restore the old stack that we found when
1429 we installed ours */
1430 sigaltstack(&old_stack, NULL);
1431 } else {
1432 /* Someone switched to a different alt stack and didn't
1433 restore ours when they were done (if they're done).
1434 There's not much we can do in this unlikely case */
1435 }
1436 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001437 PyMem_Free(stack.ss_sp);
1438 stack.ss_sp = NULL;
1439 }
1440#endif
1441}