blob: e7a285033051dfc511440574f7f255ef325b1573 [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 <signal.h>
5#include <object.h>
6#include <frameobject.h>
7#include <signal.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +02008#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinner7a399122014-09-30 13:40:12 +02009# include <pthread.h>
10#endif
11#ifdef MS_WINDOWS
12# include <windows.h>
13#endif
14#ifdef HAVE_SYS_RESOURCE_H
15# include <sys/resource.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +020016#endif
17
Victor Stinner8c663fd2017-11-08 14:44:44 -080018/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
19#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
Victor Stinner96994402011-04-07 11:37:19 +020020
Victor Stinner024e37a2011-03-31 01:31:06 +020021#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020022 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
23 SIGILL can be handled by the process, and these signals can only be used
24 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020025# define FAULTHANDLER_USER
26#endif
27
Victor Stinnerc7489a52015-04-01 18:48:58 +020028#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
Victor Stinner024e37a2011-03-31 01:31:06 +020029
Victor Stinnerbd303c12013-11-07 23:07:29 +010030_Py_IDENTIFIER(enable);
31_Py_IDENTIFIER(fileno);
32_Py_IDENTIFIER(flush);
33_Py_IDENTIFIER(stderr);
34
Victor Stinner024e37a2011-03-31 01:31:06 +020035#ifdef HAVE_SIGACTION
36typedef struct sigaction _Py_sighandler_t;
37#else
38typedef PyOS_sighandler_t _Py_sighandler_t;
39#endif
40
41typedef struct {
42 int signum;
43 int enabled;
44 const char* name;
45 _Py_sighandler_t previous;
46 int all_threads;
47} fault_handler_t;
48
49static struct {
50 int enabled;
51 PyObject *file;
52 int fd;
53 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020054 PyInterpreterState *interp;
Victor Stinner46c2b812017-04-21 18:06:13 +020055#ifdef MS_WINDOWS
56 void *exc_handler;
57#endif
Victor Stinner024e37a2011-03-31 01:31:06 +020058} fatal_error = {0, NULL, -1, 0};
59
Victor Stinner024e37a2011-03-31 01:31:06 +020060static struct {
61 PyObject *file;
62 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020063 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020064 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020065 PyInterpreterState *interp;
66 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020067 char *header;
68 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020069 /* The main thread always holds this lock. It is only released when
70 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020071 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020072 PyThread_type_lock cancel_event;
73 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020074 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020075} thread;
Victor Stinner024e37a2011-03-31 01:31:06 +020076
77#ifdef FAULTHANDLER_USER
78typedef struct {
79 int enabled;
80 PyObject *file;
81 int fd;
82 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020083 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020084 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020085 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020086} user_signal_t;
87
88static user_signal_t *user_signals;
89
90/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +020091#ifndef NSIG
92# if defined(_NSIG)
93# define NSIG _NSIG /* For BSD/SysV */
94# elif defined(_SIGMAX)
95# define NSIG (_SIGMAX + 1) /* For QNX */
96# elif defined(SIGMAX)
97# define NSIG (SIGMAX + 1) /* For djgpp */
98# else
99# define NSIG 64 /* Use a reasonable default value */
100# endif
101#endif
102
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200103static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200104#endif /* FAULTHANDLER_USER */
105
106
107static fault_handler_t faulthandler_handlers[] = {
108#ifdef SIGBUS
109 {SIGBUS, 0, "Bus error", },
110#endif
111#ifdef SIGILL
112 {SIGILL, 0, "Illegal instruction", },
113#endif
114 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200115 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200116 /* define SIGSEGV at the end to make it the default choice if searching the
117 handler fails in faulthandler_fatal_error() */
118 {SIGSEGV, 0, "Segmentation fault", }
119};
Victor Stinner404cdc52016-03-23 10:39:17 +0100120static const size_t faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200121 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200122
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100123/* Using an alternative stack requires sigaltstack()
124 and sigaction() SA_ONSTACK */
125#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
126# define FAULTHANDLER_USE_ALT_STACK
127#endif
128
129#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +0200130static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700131static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200132#endif
133
134
135/* Get the file descriptor of a file by calling its fileno() method and then
136 call its flush() method.
137
138 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100139 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200140
Victor Stinner95bb7142015-03-12 15:32:03 +0100141 On success, return the file descriptor and write the new file into *file_ptr.
142 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200143
Victor Stinner95bb7142015-03-12 15:32:03 +0100144static int
145faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200146{
147 PyObject *result;
148 long fd_long;
149 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100150 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200151
152 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100153 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200154 if (file == NULL) {
155 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100156 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200157 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200158 if (file == Py_None) {
159 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100160 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200161 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200162 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100163 else if (PyLong_Check(file)) {
164 fd = _PyLong_AsInt(file);
165 if (fd == -1 && PyErr_Occurred())
166 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700167 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100168 PyErr_SetString(PyExc_ValueError,
169 "file is not a valid file descripter");
170 return -1;
171 }
172 *file_ptr = NULL;
173 return fd;
174 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200175
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200176 result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno);
Victor Stinner024e37a2011-03-31 01:31:06 +0200177 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100178 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200179
180 fd = -1;
181 if (PyLong_Check(result)) {
182 fd_long = PyLong_AsLong(result);
183 if (0 <= fd_long && fd_long < INT_MAX)
184 fd = (int)fd_long;
185 }
186 Py_DECREF(result);
187
188 if (fd == -1) {
189 PyErr_SetString(PyExc_RuntimeError,
190 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100191 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200192 }
193
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200194 result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200195 if (result != NULL)
196 Py_DECREF(result);
197 else {
198 /* ignore flush() error */
199 PyErr_Clear();
200 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100201 *file_ptr = file;
202 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200203}
204
Victor Stinnera4de6d82011-04-09 00:47:23 +0200205/* Get the state of the current thread: only call this function if the current
206 thread holds the GIL. Raise an exception on error. */
207static PyThreadState*
208get_thread_state(void)
209{
Victor Stinner861d9ab2016-03-16 22:45:24 +0100210 PyThreadState *tstate = _PyThreadState_UncheckedGet();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200211 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100212 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200213 PyErr_SetString(PyExc_RuntimeError,
214 "unable to get the current thread state");
215 return NULL;
216 }
217 return tstate;
218}
219
Victor Stinnerc7489a52015-04-01 18:48:58 +0200220static void
221faulthandler_dump_traceback(int fd, int all_threads,
222 PyInterpreterState *interp)
223{
224 static volatile int reentrant = 0;
225 PyThreadState *tstate;
226
227 if (reentrant)
228 return;
229
230 reentrant = 1;
231
Victor Stinnerc7489a52015-04-01 18:48:58 +0200232 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
233 are thus delivered to the thread that caused the fault. Get the Python
234 thread state of the current thread.
235
236 PyThreadState_Get() doesn't give the state of the thread that caused the
237 fault if the thread released the GIL, and so this function cannot be
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900238 used. Read the thread specific storage (TSS) instead: call
Victor Stinnerc7489a52015-04-01 18:48:58 +0200239 PyGILState_GetThisThreadState(). */
240 tstate = PyGILState_GetThisThreadState();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200241
Victor Stinner861d9ab2016-03-16 22:45:24 +0100242 if (all_threads) {
243 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
244 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200245 else {
246 if (tstate != NULL)
247 _Py_DumpTraceback(fd, tstate);
248 }
249
250 reentrant = 0;
251}
252
Victor Stinner024e37a2011-03-31 01:31:06 +0200253static PyObject*
254faulthandler_dump_traceback_py(PyObject *self,
255 PyObject *args, PyObject *kwargs)
256{
257 static char *kwlist[] = {"file", "all_threads", NULL};
258 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200259 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200260 PyThreadState *tstate;
261 const char *errmsg;
262 int fd;
263
264 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
265 "|Oi:dump_traceback", kwlist,
266 &file, &all_threads))
267 return NULL;
268
Victor Stinner95bb7142015-03-12 15:32:03 +0100269 fd = faulthandler_get_fileno(&file);
270 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200271 return NULL;
272
Victor Stinnera4de6d82011-04-09 00:47:23 +0200273 tstate = get_thread_state();
274 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200275 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200276
277 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100278 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200279 if (errmsg != NULL) {
280 PyErr_SetString(PyExc_RuntimeError, errmsg);
281 return NULL;
282 }
283 }
284 else {
285 _Py_DumpTraceback(fd, tstate);
286 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200287
288 if (PyErr_CheckSignals())
289 return NULL;
290
Victor Stinner024e37a2011-03-31 01:31:06 +0200291 Py_RETURN_NONE;
292}
293
Victor Stinner404cdc52016-03-23 10:39:17 +0100294static void
295faulthandler_disable_fatal_handler(fault_handler_t *handler)
296{
297 if (!handler->enabled)
298 return;
299 handler->enabled = 0;
300#ifdef HAVE_SIGACTION
301 (void)sigaction(handler->signum, &handler->previous, NULL);
302#else
303 (void)signal(handler->signum, handler->previous);
304#endif
305}
306
Victor Stinner024e37a2011-03-31 01:31:06 +0200307
Victor Stinner410dd7d2011-05-11 20:56:08 +0200308/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200309
310 Display the current Python traceback, restore the previous handler and call
311 the previous handler.
312
Victor Stinner410dd7d2011-05-11 20:56:08 +0200313 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200314 signal handler would not be called (for an unknown reason). The execution of
315 the program continues at faulthandler_fatal_error() exit, but the same
316 instruction will raise the same fault (signal), and so the previous handler
317 will be called.
318
Victor Stinner410dd7d2011-05-11 20:56:08 +0200319 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200320
321static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200322faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200323{
324 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100325 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200326 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200327 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200328
329 if (!fatal_error.enabled)
330 return;
331
332 for (i=0; i < faulthandler_nsignals; i++) {
333 handler = &faulthandler_handlers[i];
334 if (handler->signum == signum)
335 break;
336 }
337 if (handler == NULL) {
338 /* faulthandler_nsignals == 0 (unlikely) */
339 return;
340 }
341
342 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100343 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200344
345 PUTS(fd, "Fatal Python error: ");
346 PUTS(fd, handler->name);
347 PUTS(fd, "\n\n");
348
Victor Stinnerc7489a52015-04-01 18:48:58 +0200349 faulthandler_dump_traceback(fd, fatal_error.all_threads,
350 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200351
Victor Stinnerc9256172011-05-07 12:20:11 +0200352 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200353#ifdef MS_WINDOWS
354 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200355 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200356 handler, because the Windows signal handler would not be called */
357 return;
358 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200359#endif
R David Murrayfc069992013-12-13 20:52:19 -0500360 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200361 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
362 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200363}
364
Victor Stinner404cdc52016-03-23 10:39:17 +0100365#ifdef MS_WINDOWS
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700366static int
367faulthandler_ignore_exception(DWORD code)
368{
369 /* bpo-30557: ignore exceptions which are not errors */
370 if (!(code & 0x80000000)) {
371 return 1;
372 }
373 /* bpo-31701: ignore MSC and COM exceptions
374 E0000000 + code */
375 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
376 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
377 return 1;
378 }
379 /* Interesting exception: log it with the Python traceback */
380 return 0;
381}
382
Victor Stinner404cdc52016-03-23 10:39:17 +0100383static LONG WINAPI
384faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
385{
386 const int fd = fatal_error.fd;
387 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100388 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100389
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700390 if (faulthandler_ignore_exception(code)) {
391 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100392 return EXCEPTION_CONTINUE_SEARCH;
393 }
394
395 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100396 switch (code)
397 {
398 /* only format most common errors */
399 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
400 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
401 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
402 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
403 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
404 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
405 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
406 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700407 PUTS(fd, "code 0x");
408 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100409 }
410 PUTS(fd, "\n\n");
411
412 if (code == EXCEPTION_ACCESS_VIOLATION) {
413 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200414 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100415 fault_handler_t *handler = &faulthandler_handlers[i];
416 if (handler->signum == SIGSEGV) {
417 faulthandler_disable_fatal_handler(handler);
418 break;
419 }
420 }
421 }
422
423 faulthandler_dump_traceback(fd, fatal_error.all_threads,
424 fatal_error.interp);
425
426 /* call the next exception handler */
427 return EXCEPTION_CONTINUE_SEARCH;
428}
429#endif
430
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100431
432#ifdef FAULTHANDLER_USE_ALT_STACK
433static int
434faulthandler_allocate_stack(void)
435{
436 if (stack.ss_sp != NULL) {
437 return 0;
438 }
439 /* Allocate an alternate stack for faulthandler() signal handler
440 to be able to execute a signal handler on a stack overflow error */
441 stack.ss_sp = PyMem_Malloc(stack.ss_size);
442 if (stack.ss_sp == NULL) {
443 PyErr_NoMemory();
444 return -1;
445 }
446
447 int err = sigaltstack(&stack, &old_stack);
448 if (err) {
449 /* Release the stack to retry sigaltstack() next time */
450 PyMem_Free(stack.ss_sp);
451 stack.ss_sp = NULL;
452
453 PyErr_SetFromErrno(PyExc_OSError);
454 return -1;
455 }
456 return 0;
457}
458#endif
459
460
Victor Stinnerd727e232011-04-01 12:13:55 +0200461/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200462
doko@ubuntu.combc731502016-05-18 01:06:01 +0200463static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100464faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200465{
Victor Stinner404cdc52016-03-23 10:39:17 +0100466 if (fatal_error.enabled) {
467 return 0;
468 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100469 fatal_error.enabled = 1;
470
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100471#ifdef FAULTHANDLER_USE_ALT_STACK
472 if (faulthandler_allocate_stack() < 0) {
473 return -1;
474 }
475#endif
476
Victor Stinner46c2b812017-04-21 18:06:13 +0200477 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100478 fault_handler_t *handler;
Victor Stinner928ad282016-03-23 15:19:12 +0100479 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100480
Victor Stinner928ad282016-03-23 15:19:12 +0100481 handler = &faulthandler_handlers[i];
482 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100483#ifdef HAVE_SIGACTION
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100484 struct sigaction action;
Victor Stinner404cdc52016-03-23 10:39:17 +0100485 action.sa_handler = faulthandler_fatal_error;
486 sigemptyset(&action.sa_mask);
487 /* Do not prevent the signal from being received from within
488 its own signal handler */
489 action.sa_flags = SA_NODEFER;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100490#ifdef FAULTHANDLER_USE_ALT_STACK
491 assert(stack.ss_sp != NULL);
492 /* Call the signal handler on an alternate signal stack
493 provided by sigaltstack() */
494 action.sa_flags |= SA_ONSTACK;
Victor Stinner404cdc52016-03-23 10:39:17 +0100495#endif
496 err = sigaction(handler->signum, &action, &handler->previous);
497#else
498 handler->previous = signal(handler->signum,
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100499 faulthandler_fatal_error);
Victor Stinner404cdc52016-03-23 10:39:17 +0100500 err = (handler->previous == SIG_ERR);
501#endif
502 if (err) {
503 PyErr_SetFromErrno(PyExc_RuntimeError);
504 return -1;
505 }
506
507 handler->enabled = 1;
508 }
509
510#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200511 assert(fatal_error.exc_handler == NULL);
512 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100513#endif
514 return 0;
515}
516
517static PyObject*
518faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
519{
520 static char *kwlist[] = {"file", "all_threads", NULL};
521 PyObject *file = NULL;
522 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200523 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200524 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200525
526 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
527 "|Oi:enable", kwlist, &file, &all_threads))
528 return NULL;
529
Victor Stinner95bb7142015-03-12 15:32:03 +0100530 fd = faulthandler_get_fileno(&file);
531 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200532 return NULL;
533
Victor Stinnera4de6d82011-04-09 00:47:23 +0200534 tstate = get_thread_state();
535 if (tstate == NULL)
536 return NULL;
537
Victor Stinner95bb7142015-03-12 15:32:03 +0100538 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300539 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200540 fatal_error.fd = fd;
541 fatal_error.all_threads = all_threads;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100542 fatal_error.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200543
Victor Stinner404cdc52016-03-23 10:39:17 +0100544 if (faulthandler_enable() < 0) {
545 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200546 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100547
Victor Stinner024e37a2011-03-31 01:31:06 +0200548 Py_RETURN_NONE;
549}
550
551static void
552faulthandler_disable(void)
553{
Victor Stinner024e37a2011-03-31 01:31:06 +0200554 if (fatal_error.enabled) {
555 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200556 for (size_t i=0; i < faulthandler_nsignals; i++) {
557 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200558 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100559 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200560 }
561 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200562#ifdef MS_WINDOWS
563 if (fatal_error.exc_handler != NULL) {
564 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
565 fatal_error.exc_handler = NULL;
566 }
567#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200568 Py_CLEAR(fatal_error.file);
569}
570
571static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530572faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200573{
574 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200575 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200576 }
577 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200578 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200579}
580
581static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530582faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200583{
584 return PyBool_FromLong(fatal_error.enabled);
585}
586
Victor Stinner024e37a2011-03-31 01:31:06 +0200587static void
588faulthandler_thread(void *unused)
589{
590 PyLockStatus st;
591 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200592 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200593#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200594 sigset_t set;
595
596 /* we don't want to receive any signal */
597 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200598 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200599#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200600
601 do {
602 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200603 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200604 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200605 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200606 break;
607 }
608 /* Timeout => dump traceback */
609 assert(st == PY_LOCK_FAILURE);
610
Victor Stinnerc7489a52015-04-01 18:48:58 +0200611 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200612
Victor Stinner861d9ab2016-03-16 22:45:24 +0100613 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200614 ok = (errmsg == NULL);
615
616 if (thread.exit)
617 _exit(1);
618 } while (ok && thread.repeat);
619
620 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200621 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200622}
623
624static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200625cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200626{
Thomas A Caswelle2783352019-08-29 12:30:04 -0400627 /* If not scheduled, nothing to cancel */
628 if (!thread.cancel_event) {
629 return;
630 }
631
Victor Stinner410dd7d2011-05-11 20:56:08 +0200632 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200633 PyThread_release_lock(thread.cancel_event);
634
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200635 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200636 PyThread_acquire_lock(thread.running, 1);
637 PyThread_release_lock(thread.running);
638
639 /* The main thread should always hold the cancel_event lock */
640 PyThread_acquire_lock(thread.cancel_event, 1);
641
Victor Stinner024e37a2011-03-31 01:31:06 +0200642 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200643 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200644 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200645 thread.header = NULL;
646 }
647}
648
Victor Stinner93fd4782017-10-27 07:27:12 -0700649#define SEC_TO_US (1000 * 1000)
650
Victor Stinnerc790a532011-04-08 13:39:59 +0200651static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700652format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200653{
Victor Stinner93fd4782017-10-27 07:27:12 -0700654 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200655 char buffer[100];
656
Victor Stinner93fd4782017-10-27 07:27:12 -0700657 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
658 sec = (unsigned long)(us / SEC_TO_US);
659 us %= SEC_TO_US;
660
Victor Stinnerc790a532011-04-08 13:39:59 +0200661 min = sec / 60;
662 sec %= 60;
663 hour = min / 60;
664 min %= 60;
665
Victor Stinner93fd4782017-10-27 07:27:12 -0700666 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200667 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700668 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
669 hour, min, sec, (unsigned int)us);
670 }
671 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200672 PyOS_snprintf(buffer, sizeof(buffer),
673 "Timeout (%lu:%02lu:%02lu)!\n",
674 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700675 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200676 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200677}
678
679static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200680faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200681 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200682{
683 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700684 PyObject *timeout_obj;
685 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200686 int repeat = 0;
687 PyObject *file = NULL;
688 int fd;
689 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200690 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200691 char *header;
692 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200693
694 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700695 "O|iOi:dump_traceback_later", kwlist,
696 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200697 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700698
699 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
700 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200701 return NULL;
702 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700703 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200704 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200705 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
706 return NULL;
707 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700708 /* Limit to LONG_MAX seconds for format_timeout() */
709 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
710 PyErr_SetString(PyExc_OverflowError,
711 "timeout value is too large");
712 return NULL;
713 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200714
Victor Stinnera4de6d82011-04-09 00:47:23 +0200715 tstate = get_thread_state();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100716 if (tstate == NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200717 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100718 }
Victor Stinner96994402011-04-07 11:37:19 +0200719
Victor Stinner95bb7142015-03-12 15:32:03 +0100720 fd = faulthandler_get_fileno(&file);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100721 if (fd < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200722 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100723 }
724
725 if (!thread.running) {
726 thread.running = PyThread_allocate_lock();
727 if (!thread.running) {
728 return PyErr_NoMemory();
729 }
730 }
731 if (!thread.cancel_event) {
732 thread.cancel_event = PyThread_allocate_lock();
733 if (!thread.cancel_event || !thread.running) {
734 return PyErr_NoMemory();
735 }
736
737 /* cancel_event starts to be acquired: it's only released to cancel
738 the thread. */
739 PyThread_acquire_lock(thread.cancel_event, 1);
740 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200741
Victor Stinnerc790a532011-04-08 13:39:59 +0200742 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700743 header = format_timeout(timeout_us);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100744 if (header == NULL) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200745 return PyErr_NoMemory();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100746 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200747 header_len = strlen(header);
748
Victor Stinner024e37a2011-03-31 01:31:06 +0200749 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200750 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200751
Victor Stinner95bb7142015-03-12 15:32:03 +0100752 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300753 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200754 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700755 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
756 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200757 thread.repeat = repeat;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100758 thread.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200759 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200760 thread.header = header;
761 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200762
763 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200764 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200765
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200766 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200767 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200768 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200769 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200770 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200771 PyErr_SetString(PyExc_RuntimeError,
772 "unable to start watchdog thread");
773 return NULL;
774 }
775
776 Py_RETURN_NONE;
777}
778
779static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530780faulthandler_cancel_dump_traceback_later_py(PyObject *self,
781 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200782{
Georg Brandldeb92b52012-09-22 08:58:55 +0200783 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200784 Py_RETURN_NONE;
785}
Victor Stinner024e37a2011-03-31 01:31:06 +0200786
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100787
Victor Stinner024e37a2011-03-31 01:31:06 +0200788#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200789static int
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100790faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200791{
792#ifdef HAVE_SIGACTION
793 struct sigaction action;
794 action.sa_handler = faulthandler_user;
795 sigemptyset(&action.sa_mask);
796 /* if the signal is received while the kernel is executing a system
797 call, try to restart the system call instead of interrupting it and
798 return EINTR. */
799 action.sa_flags = SA_RESTART;
800 if (chain) {
801 /* do not prevent the signal from being received from within its
802 own signal handler */
803 action.sa_flags = SA_NODEFER;
804 }
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100805#ifdef FAULTHANDLER_USE_ALT_STACK
806 assert(stack.ss_sp != NULL);
807 /* Call the signal handler on an alternate signal stack
808 provided by sigaltstack() */
809 action.sa_flags |= SA_ONSTACK;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200810#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100811 return sigaction(signum, &action, previous_p);
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200812#else
813 _Py_sighandler_t previous;
814 previous = signal(signum, faulthandler_user);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100815 if (previous_p != NULL) {
816 *previous_p = previous;
817 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200818 return (previous == SIG_ERR);
819#endif
820}
821
Victor Stinner024e37a2011-03-31 01:31:06 +0200822/* Handler of user signals (e.g. SIGUSR1).
823
824 Dump the traceback of the current thread, or of all threads if
825 thread.all_threads is true.
826
827 This function is signal safe and should only call signal safe functions. */
828
829static void
830faulthandler_user(int signum)
831{
832 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200833 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200834
835 user = &user_signals[signum];
836 if (!user->enabled)
837 return;
838
Victor Stinnerc7489a52015-04-01 18:48:58 +0200839 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200840
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200841#ifdef HAVE_SIGACTION
842 if (user->chain) {
843 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200844 errno = save_errno;
845
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200846 /* call the previous signal handler */
847 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200848
849 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200850 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200851 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200852 }
853#else
854 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200855 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200856 /* call the previous signal handler */
857 user->previous(signum);
858 }
859#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200860}
861
862static int
863check_signum(int signum)
864{
Victor Stinner46c2b812017-04-21 18:06:13 +0200865 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200866 if (faulthandler_handlers[i].signum == signum) {
867 PyErr_Format(PyExc_RuntimeError,
868 "signal %i cannot be registered, "
869 "use enable() instead",
870 signum);
871 return 0;
872 }
873 }
874 if (signum < 1 || NSIG <= signum) {
875 PyErr_SetString(PyExc_ValueError, "signal number out of range");
876 return 0;
877 }
878 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200879}
880
881static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200882faulthandler_register_py(PyObject *self,
883 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200884{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200885 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200886 int signum;
887 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200888 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200889 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200890 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200891 user_signal_t *user;
892 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200893 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200894 int err;
895
896 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200897 "i|Oii:register", kwlist,
898 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200899 return NULL;
900
Victor Stinner44378d42011-04-01 15:37:12 +0200901 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200902 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200903
Victor Stinnera4de6d82011-04-09 00:47:23 +0200904 tstate = get_thread_state();
905 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200906 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200907
Victor Stinner95bb7142015-03-12 15:32:03 +0100908 fd = faulthandler_get_fileno(&file);
909 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200910 return NULL;
911
912 if (user_signals == NULL) {
Andy Lester7668a8b2020-03-24 23:26:44 -0500913 user_signals = PyMem_Calloc(NSIG, sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200914 if (user_signals == NULL)
915 return PyErr_NoMemory();
916 }
917 user = &user_signals[signum];
918
919 if (!user->enabled) {
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100920#ifdef FAULTHANDLER_USE_ALT_STACK
921 if (faulthandler_allocate_stack() < 0) {
922 return NULL;
923 }
924#endif
925
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200926 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200927 if (err) {
928 PyErr_SetFromErrno(PyExc_OSError);
929 return NULL;
930 }
Victor Stinner8d379542013-07-02 00:14:56 +0200931
932 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200933 }
934
Victor Stinner95bb7142015-03-12 15:32:03 +0100935 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300936 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200937 user->fd = fd;
938 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200939 user->chain = chain;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100940 user->interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200941 user->enabled = 1;
942
943 Py_RETURN_NONE;
944}
945
946static int
947faulthandler_unregister(user_signal_t *user, int signum)
948{
Victor Stinnera01ca122011-04-01 12:56:17 +0200949 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200950 return 0;
951 user->enabled = 0;
952#ifdef HAVE_SIGACTION
953 (void)sigaction(signum, &user->previous, NULL);
954#else
955 (void)signal(signum, user->previous);
956#endif
957 Py_CLEAR(user->file);
958 user->fd = -1;
959 return 1;
960}
961
962static PyObject*
963faulthandler_unregister_py(PyObject *self, PyObject *args)
964{
965 int signum;
966 user_signal_t *user;
967 int change;
968
969 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
970 return NULL;
971
Victor Stinner44378d42011-04-01 15:37:12 +0200972 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200973 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200974
Victor Stinnercfa71232011-04-08 12:48:15 +0200975 if (user_signals == NULL)
976 Py_RETURN_FALSE;
977
Victor Stinner024e37a2011-03-31 01:31:06 +0200978 user = &user_signals[signum];
979 change = faulthandler_unregister(user, signum);
980 return PyBool_FromLong(change);
981}
982#endif /* FAULTHANDLER_USER */
983
984
Victor Stinner7a399122014-09-30 13:40:12 +0200985static void
986faulthandler_suppress_crash_report(void)
987{
988#ifdef MS_WINDOWS
989 UINT mode;
990
991 /* Configure Windows to not display the Windows Error Reporting dialog */
992 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
993 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
994#endif
995
996#ifdef HAVE_SYS_RESOURCE_H
997 struct rlimit rl;
998
999 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +01001000 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +02001001 rl.rlim_cur = 0;
1002 setrlimit(RLIMIT_CORE, &rl);
1003 }
1004#endif
1005
1006#ifdef _MSC_VER
1007 /* Visual Studio: configure abort() to not display an error message nor
1008 open a popup asking to report the fault. */
1009 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1010#endif
1011}
1012
Victor Stinner024e37a2011-03-31 01:31:06 +02001013static PyObject *
1014faulthandler_read_null(PyObject *self, PyObject *args)
1015{
Victor Stinnera2477202012-01-30 00:07:43 +01001016 volatile int *x;
1017 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +01001018
Victor Stinner7a399122014-09-30 13:40:12 +02001019 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +01001020 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +02001021 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +02001022 return PyLong_FromLong(y);
1023
1024}
1025
Victor Stinner50838282014-09-30 13:54:14 +02001026static void
1027faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +02001028{
Victor Stinner7a399122014-09-30 13:40:12 +02001029 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001030#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +02001031 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
1032 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +02001033 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +02001034 SIGSEGV was raised by the kernel because of a fault, and so if the
1035 program retries to execute the same instruction, the fault will be
1036 raised again.
1037
1038 Here the fault is simulated by a fake SIGSEGV signal raised by the
1039 application. We have to raise SIGSEGV at lease twice: once for
1040 faulthandler_fatal_error(), and one more time for the previous signal
1041 handler. */
1042 while(1)
1043 raise(SIGSEGV);
1044#else
1045 raise(SIGSEGV);
1046#endif
Victor Stinner50838282014-09-30 13:54:14 +02001047}
1048
1049static PyObject *
1050faulthandler_sigsegv(PyObject *self, PyObject *args)
1051{
1052 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +01001053 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +02001054 return NULL;
1055
1056 if (release_gil) {
1057 Py_BEGIN_ALLOW_THREADS
1058 faulthandler_raise_sigsegv();
1059 Py_END_ALLOW_THREADS
1060 } else {
1061 faulthandler_raise_sigsegv();
1062 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001063 Py_RETURN_NONE;
1064}
1065
Victor Stinner2a4903f2020-01-30 13:09:11 +01001066static void _Py_NO_RETURN
Victor Stinner861d9ab2016-03-16 22:45:24 +01001067faulthandler_fatal_error_thread(void *plock)
1068{
Victor Stinner861d9ab2016-03-16 22:45:24 +01001069 Py_FatalError("in new thread");
Victor Stinner861d9ab2016-03-16 22:45:24 +01001070}
1071
1072static PyObject *
1073faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1074{
1075 long thread;
1076 PyThread_type_lock lock;
1077
1078 faulthandler_suppress_crash_report();
1079
1080 lock = PyThread_allocate_lock();
1081 if (lock == NULL)
1082 return PyErr_NoMemory();
1083
1084 PyThread_acquire_lock(lock, WAIT_LOCK);
1085
1086 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1087 if (thread == -1) {
1088 PyThread_free_lock(lock);
1089 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1090 return NULL;
1091 }
1092
1093 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001094 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001095 PyThread_acquire_lock(lock, WAIT_LOCK);
1096 PyThread_release_lock(lock);
1097 PyThread_free_lock(lock);
1098
1099 Py_RETURN_NONE;
1100}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001101
Victor Stinner024e37a2011-03-31 01:31:06 +02001102static PyObject *
1103faulthandler_sigfpe(PyObject *self, PyObject *args)
1104{
1105 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1106 PowerPC. Use volatile to disable compile-time optimizations. */
1107 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001108 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001109 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001110 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1111 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001112 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001113 /* This line is never reached, but we pretend to make something with z
1114 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001115 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001116}
1117
Victor Stinnerd727e232011-04-01 12:13:55 +02001118static PyObject *
1119faulthandler_sigabrt(PyObject *self, PyObject *args)
1120{
Victor Stinner7a399122014-09-30 13:40:12 +02001121 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001122 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001123 Py_RETURN_NONE;
1124}
1125
Victor Stinner024e37a2011-03-31 01:31:06 +02001126static PyObject *
1127faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1128{
1129 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001130 int release_gil = 0;
1131 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001132 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001133 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001134 if (release_gil) {
1135 Py_BEGIN_ALLOW_THREADS
1136 Py_FatalError(message);
1137 Py_END_ALLOW_THREADS
1138 }
1139 else {
1140 Py_FatalError(message);
1141 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001142 Py_RETURN_NONE;
1143}
1144
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001145#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001146#define FAULTHANDLER_STACK_OVERFLOW
1147
Victor Stinner8b787962019-12-04 21:10:06 +01001148static uintptr_t
Benjamin Petersonca470632016-09-06 13:47:26 -07001149stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001150{
Victor Stinner8b787962019-12-04 21:10:06 +01001151 /* Allocate (at least) 4096 bytes on the stack at each call.
1152
1153 bpo-23654, bpo-38965: use volatile keyword to prevent tail call
1154 optimization. */
1155 volatile unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001156 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001157 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001158 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001159 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001160 buffer[0] = 1;
1161 buffer[4095] = 0;
1162 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001163}
1164
1165static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301166faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001167{
1168 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001169 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001170 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001171
Victor Stinner7a399122014-09-30 13:40:12 +02001172 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001173 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001174
1175 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1176 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1177 }
1178 else {
1179 lower_limit = 0;
1180 }
1181
1182 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1183 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1184 }
1185 else {
1186 upper_limit = UINTPTR_MAX;
1187 }
1188
1189 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001190 if (sp < stop)
1191 size = stop - sp;
1192 else
1193 size = sp - stop;
1194 PyErr_Format(PyExc_RuntimeError,
1195 "unable to raise a stack overflow (allocated %zu bytes "
1196 "on the stack, %zu recursive calls)",
1197 size, depth);
1198 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001199}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001200#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001201
1202
1203static int
1204faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1205{
Victor Stinner024e37a2011-03-31 01:31:06 +02001206 Py_VISIT(thread.file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001207#ifdef FAULTHANDLER_USER
1208 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001209 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001210 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001211 }
1212#endif
1213 Py_VISIT(fatal_error.file);
1214 return 0;
1215}
1216
Victor Stinner404cdc52016-03-23 10:39:17 +01001217#ifdef MS_WINDOWS
1218static PyObject *
1219faulthandler_raise_exception(PyObject *self, PyObject *args)
1220{
1221 unsigned int code, flags = 0;
1222 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1223 return NULL;
1224 faulthandler_suppress_crash_report();
1225 RaiseException(code, flags, 0, NULL);
1226 Py_RETURN_NONE;
1227}
1228#endif
1229
Victor Stinner024e37a2011-03-31 01:31:06 +02001230PyDoc_STRVAR(module_doc,
1231"faulthandler module.");
1232
1233static PyMethodDef module_methods[] = {
1234 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001235 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001236 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001237 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301238 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001239 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301240 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001241 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1242 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001243 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001244 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001245 "dump the traceback of the current thread, or of all threads "
1246 "if all_threads is True, into file")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001247 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001248 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001249 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001250 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001251 "or each timeout seconds if repeat is True. If exit is True, "
1252 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001253 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301254 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001255 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1256 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001257#ifdef FAULTHANDLER_USER
1258 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001259 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001260 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001261 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001262 "traceback of the current thread, or of all threads if "
1263 "all_threads is True, into file")},
1264 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001265 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001266 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1267 "'signum' registered by register()")},
1268#endif
Victor Stinner50838282014-09-30 13:54:14 +02001269 {"_read_null", faulthandler_read_null, METH_NOARGS,
1270 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001271 "a SIGSEGV or SIGBUS signal depending on the platform")},
1272 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001273 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001274 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1275 PyDoc_STR("fatal_error_c_thread(): "
1276 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001277 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001278 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001279 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1280 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001281 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1282 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001283#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301284 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001285 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1286#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001287#ifdef MS_WINDOWS
1288 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1289 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1290#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001291 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001292};
1293
1294static struct PyModuleDef module_def = {
1295 PyModuleDef_HEAD_INIT,
1296 "faulthandler",
1297 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001298 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001299 module_methods,
1300 NULL,
1301 faulthandler_traverse,
1302 NULL,
1303 NULL
1304};
1305
1306PyMODINIT_FUNC
1307PyInit_faulthandler(void)
1308{
Victor Stinner404cdc52016-03-23 10:39:17 +01001309 PyObject *m = PyModule_Create(&module_def);
1310 if (m == NULL)
1311 return NULL;
1312
1313 /* Add constants for unit tests */
1314#ifdef MS_WINDOWS
1315 /* RaiseException() codes (prefixed by an underscore) */
1316 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
Brandt Bucherac223542019-11-19 15:13:05 -08001317 EXCEPTION_ACCESS_VIOLATION)) {
1318 goto error;
1319 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001320 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
Brandt Bucherac223542019-11-19 15:13:05 -08001321 EXCEPTION_INT_DIVIDE_BY_ZERO)) {
1322 goto error;
1323 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001324 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
Brandt Bucherac223542019-11-19 15:13:05 -08001325 EXCEPTION_STACK_OVERFLOW)) {
1326 goto error;
1327 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001328
1329 /* RaiseException() flags (prefixed by an underscore) */
1330 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
Brandt Bucherac223542019-11-19 15:13:05 -08001331 EXCEPTION_NONCONTINUABLE)) {
1332 goto error;
1333 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001334 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
Brandt Bucherac223542019-11-19 15:13:05 -08001335 EXCEPTION_NONCONTINUABLE_EXCEPTION)) {
1336 goto error;
1337 }
Victor Stinner404cdc52016-03-23 10:39:17 +01001338#endif
1339
1340 return m;
Brandt Bucherac223542019-11-19 15:13:05 -08001341
1342#ifdef MS_WINDOWS
1343error:
1344 Py_DECREF(m);
1345 return NULL;
1346#endif
Victor Stinner024e37a2011-03-31 01:31:06 +02001347}
1348
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001349static int
1350faulthandler_init_enable(void)
1351{
1352 PyObject *module = PyImport_ImportModule("faulthandler");
1353 if (module == NULL) {
1354 return -1;
1355 }
1356
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001357 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001358 Py_DECREF(module);
1359 if (res == NULL) {
1360 return -1;
1361 }
1362 Py_DECREF(res);
1363
1364 return 0;
1365}
1366
Victor Stinner331a6a52019-05-27 16:39:22 +02001367PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001368_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001369{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001370#ifdef FAULTHANDLER_USE_ALT_STACK
1371 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001372 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001373 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1374 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1375 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1376 platforms. */
1377 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001378#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001379
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001380 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001381
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001382 if (enable) {
1383 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001384 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001385 }
1386 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001387 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001388}
1389
1390void _PyFaulthandler_Fini(void)
1391{
Victor Stinner024e37a2011-03-31 01:31:06 +02001392 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001393 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001394 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001395 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001396 PyThread_free_lock(thread.cancel_event);
1397 thread.cancel_event = NULL;
1398 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001399 if (thread.running) {
1400 PyThread_free_lock(thread.running);
1401 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001402 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001403
1404#ifdef FAULTHANDLER_USER
1405 /* user */
1406 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001407 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001408 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001409 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001410 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001411 user_signals = NULL;
1412 }
1413#endif
1414
1415 /* fatal */
1416 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001417
1418#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001419 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001420 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001421 stack_t current_stack;
1422 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001423 if (sigaltstack(NULL, &current_stack) == 0) {
1424 if (current_stack.ss_sp == stack.ss_sp) {
1425 /* The current alt stack is the one that we installed.
1426 It is safe to restore the old stack that we found when
1427 we installed ours */
1428 sigaltstack(&old_stack, NULL);
1429 } else {
1430 /* Someone switched to a different alt stack and didn't
1431 restore ours when they were done (if they're done).
1432 There's not much we can do in this unlikely case */
1433 }
1434 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001435 PyMem_Free(stack.ss_sp);
1436 stack.ss_sp = NULL;
1437 }
1438#endif
1439}