blob: 129a104dba3f335a539cfe92d0e9501aeaddbac7 [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 Stinner861d9ab2016-03-16 22:45:24 +01001068static void
1069faulthandler_fatal_error_thread(void *plock)
1070{
Victor Stinner9a2329f2016-12-05 17:56:36 +01001071#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +01001072 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +01001073#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001074
1075 Py_FatalError("in new thread");
1076
Victor Stinner9a2329f2016-12-05 17:56:36 +01001077#ifndef __clang__
1078 /* Issue #28152: Py_FatalError() is declared with
1079 __attribute__((__noreturn__)). GCC emits a warning without
1080 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
1081 emits a warning on the return. */
1082
Victor Stinner861d9ab2016-03-16 22:45:24 +01001083 /* notify the caller that we are done */
1084 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +01001085#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001086}
1087
1088static PyObject *
1089faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1090{
1091 long thread;
1092 PyThread_type_lock lock;
1093
1094 faulthandler_suppress_crash_report();
1095
1096 lock = PyThread_allocate_lock();
1097 if (lock == NULL)
1098 return PyErr_NoMemory();
1099
1100 PyThread_acquire_lock(lock, WAIT_LOCK);
1101
1102 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1103 if (thread == -1) {
1104 PyThread_free_lock(lock);
1105 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1106 return NULL;
1107 }
1108
1109 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001110 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001111 PyThread_acquire_lock(lock, WAIT_LOCK);
1112 PyThread_release_lock(lock);
1113 PyThread_free_lock(lock);
1114
1115 Py_RETURN_NONE;
1116}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001117
Victor Stinner024e37a2011-03-31 01:31:06 +02001118static PyObject *
1119faulthandler_sigfpe(PyObject *self, PyObject *args)
1120{
1121 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1122 PowerPC. Use volatile to disable compile-time optimizations. */
1123 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001124 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001125 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001126 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1127 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001128 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001129 /* This line is never reached, but we pretend to make something with z
1130 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001131 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001132}
1133
Victor Stinnerd727e232011-04-01 12:13:55 +02001134static PyObject *
1135faulthandler_sigabrt(PyObject *self, PyObject *args)
1136{
Victor Stinner7a399122014-09-30 13:40:12 +02001137 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001138 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001139 Py_RETURN_NONE;
1140}
1141
Victor Stinner024e37a2011-03-31 01:31:06 +02001142static PyObject *
1143faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1144{
1145 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001146 int release_gil = 0;
1147 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001148 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001149 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001150 if (release_gil) {
1151 Py_BEGIN_ALLOW_THREADS
1152 Py_FatalError(message);
1153 Py_END_ALLOW_THREADS
1154 }
1155 else {
1156 Py_FatalError(message);
1157 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001158 Py_RETURN_NONE;
1159}
1160
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001161#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001162#define FAULTHANDLER_STACK_OVERFLOW
1163
Victor Stinner19276f12015-03-23 21:20:27 +01001164#ifdef __INTEL_COMPILER
1165 /* Issue #23654: Turn off ICC's tail call optimization for the
1166 * stack_overflow generator. ICC turns the recursive tail call into
1167 * a loop. */
1168# pragma intel optimization_level 0
1169#endif
1170static
Benjamin Petersonca470632016-09-06 13:47:26 -07001171uintptr_t
1172stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001173{
1174 /* allocate 4096 bytes on the stack at each call */
1175 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001176 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001177 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001178 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001179 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001180 buffer[0] = 1;
1181 buffer[4095] = 0;
1182 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001183}
1184
1185static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301186faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001187{
1188 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001189 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001190 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001191
Victor Stinner7a399122014-09-30 13:40:12 +02001192 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001193 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001194
1195 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1196 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1197 }
1198 else {
1199 lower_limit = 0;
1200 }
1201
1202 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1203 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1204 }
1205 else {
1206 upper_limit = UINTPTR_MAX;
1207 }
1208
1209 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001210 if (sp < stop)
1211 size = stop - sp;
1212 else
1213 size = sp - stop;
1214 PyErr_Format(PyExc_RuntimeError,
1215 "unable to raise a stack overflow (allocated %zu bytes "
1216 "on the stack, %zu recursive calls)",
1217 size, depth);
1218 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001219}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001220#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001221
1222
1223static int
1224faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1225{
Victor Stinner024e37a2011-03-31 01:31:06 +02001226 Py_VISIT(thread.file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001227#ifdef FAULTHANDLER_USER
1228 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001229 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001230 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001231 }
1232#endif
1233 Py_VISIT(fatal_error.file);
1234 return 0;
1235}
1236
Victor Stinner404cdc52016-03-23 10:39:17 +01001237#ifdef MS_WINDOWS
1238static PyObject *
1239faulthandler_raise_exception(PyObject *self, PyObject *args)
1240{
1241 unsigned int code, flags = 0;
1242 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1243 return NULL;
1244 faulthandler_suppress_crash_report();
1245 RaiseException(code, flags, 0, NULL);
1246 Py_RETURN_NONE;
1247}
1248#endif
1249
Victor Stinner024e37a2011-03-31 01:31:06 +02001250PyDoc_STRVAR(module_doc,
1251"faulthandler module.");
1252
1253static PyMethodDef module_methods[] = {
1254 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001255 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001256 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001257 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301258 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001259 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301260 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001261 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1262 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001263 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001264 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001265 "dump the traceback of the current thread, or of all threads "
1266 "if all_threads is True, into file")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001267 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001268 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001269 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001270 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001271 "or each timeout seconds if repeat is True. If exit is True, "
1272 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001273 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301274 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001275 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1276 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001277#ifdef FAULTHANDLER_USER
1278 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001279 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001280 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001281 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001282 "traceback of the current thread, or of all threads if "
1283 "all_threads is True, into file")},
1284 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001285 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001286 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1287 "'signum' registered by register()")},
1288#endif
Victor Stinner50838282014-09-30 13:54:14 +02001289 {"_read_null", faulthandler_read_null, METH_NOARGS,
1290 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001291 "a SIGSEGV or SIGBUS signal depending on the platform")},
1292 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001293 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001294 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1295 PyDoc_STR("fatal_error_c_thread(): "
1296 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001297 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001298 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001299 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1300 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001301 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1302 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001303#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301304 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001305 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1306#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001307#ifdef MS_WINDOWS
1308 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1309 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1310#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001311 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001312};
1313
1314static struct PyModuleDef module_def = {
1315 PyModuleDef_HEAD_INIT,
1316 "faulthandler",
1317 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001318 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001319 module_methods,
1320 NULL,
1321 faulthandler_traverse,
1322 NULL,
1323 NULL
1324};
1325
1326PyMODINIT_FUNC
1327PyInit_faulthandler(void)
1328{
Victor Stinner404cdc52016-03-23 10:39:17 +01001329 PyObject *m = PyModule_Create(&module_def);
1330 if (m == NULL)
1331 return NULL;
1332
1333 /* Add constants for unit tests */
1334#ifdef MS_WINDOWS
1335 /* RaiseException() codes (prefixed by an underscore) */
1336 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1337 EXCEPTION_ACCESS_VIOLATION))
1338 return NULL;
1339 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1340 EXCEPTION_INT_DIVIDE_BY_ZERO))
1341 return NULL;
1342 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1343 EXCEPTION_STACK_OVERFLOW))
1344 return NULL;
1345
1346 /* RaiseException() flags (prefixed by an underscore) */
1347 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1348 EXCEPTION_NONCONTINUABLE))
1349 return NULL;
1350 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1351 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1352 return NULL;
1353#endif
1354
1355 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001356}
1357
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001358static int
1359faulthandler_init_enable(void)
1360{
1361 PyObject *module = PyImport_ImportModule("faulthandler");
1362 if (module == NULL) {
1363 return -1;
1364 }
1365
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001366 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001367 Py_DECREF(module);
1368 if (res == NULL) {
1369 return -1;
1370 }
1371 Py_DECREF(res);
1372
1373 return 0;
1374}
1375
Victor Stinner331a6a52019-05-27 16:39:22 +02001376PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001377_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001378{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001379#ifdef FAULTHANDLER_USE_ALT_STACK
1380 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001381 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001382 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1383 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1384 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1385 platforms. */
1386 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001387#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001388
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001389 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001390
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001391 if (enable) {
1392 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001393 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001394 }
1395 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001396 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001397}
1398
1399void _PyFaulthandler_Fini(void)
1400{
Victor Stinner024e37a2011-03-31 01:31:06 +02001401 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001402 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001403 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001404 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001405 PyThread_free_lock(thread.cancel_event);
1406 thread.cancel_event = NULL;
1407 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001408 if (thread.running) {
1409 PyThread_free_lock(thread.running);
1410 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001411 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001412
1413#ifdef FAULTHANDLER_USER
1414 /* user */
1415 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001416 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001417 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001418 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001419 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001420 user_signals = NULL;
1421 }
1422#endif
1423
1424 /* fatal */
1425 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001426
1427#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001428 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001429 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001430 stack_t current_stack;
1431 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001432 if (sigaltstack(NULL, &current_stack) == 0) {
1433 if (current_stack.ss_sp == stack.ss_sp) {
1434 /* The current alt stack is the one that we installed.
1435 It is safe to restore the old stack that we found when
1436 we installed ours */
1437 sigaltstack(&old_stack, NULL);
1438 } else {
1439 /* Someone switched to a different alt stack and didn't
1440 restore ours when they were done (if they're done).
1441 There's not much we can do in this unlikely case */
1442 }
1443 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001444 PyMem_Free(stack.ss_sp);
1445 stack.ss_sp = NULL;
1446 }
1447#endif
1448}