blob: 350f4cf6b8edffe99883ae93cdc1b2ca4debe0ba [file] [log] [blame]
Victor Stinner024e37a2011-03-31 01:31:06 +02001#include "Python.h"
Victor Stinnere2320252021-01-18 18:24:29 +01002#include "pycore_initconfig.h" // _PyStatus_ERR
Victor Stinner250035d2021-01-18 20:47:13 +01003#include "pycore_pyerrors.h" // _Py_DumpExtensionModules
Victor Stinner5592f2b2021-02-19 13:21:28 +01004#include "pycore_pystate.h" // _PyThreadState_GET()
Victor Stinnere2320252021-01-18 18:24:29 +01005#include "pycore_traceback.h" // _Py_DumpTracebackThreads
Victor Stinner024e37a2011-03-31 01:31:06 +02006#include <signal.h>
7#include <object.h>
8#include <frameobject.h>
9#include <signal.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +020010#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinner7a399122014-09-30 13:40:12 +020011# include <pthread.h>
12#endif
13#ifdef MS_WINDOWS
14# include <windows.h>
15#endif
16#ifdef HAVE_SYS_RESOURCE_H
17# include <sys/resource.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +020018#endif
19
Victor Stinner8c663fd2017-11-08 14:44:44 -080020/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
21#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
Victor Stinner96994402011-04-07 11:37:19 +020022
Victor Stinner024e37a2011-03-31 01:31:06 +020023#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020024 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
25 SIGILL can be handled by the process, and these signals can only be used
26 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020027# define FAULTHANDLER_USER
28#endif
29
Victor Stinnerc7489a52015-04-01 18:48:58 +020030#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
Victor Stinner024e37a2011-03-31 01:31:06 +020031
Victor Stinnerbd303c12013-11-07 23:07:29 +010032_Py_IDENTIFIER(enable);
33_Py_IDENTIFIER(fileno);
34_Py_IDENTIFIER(flush);
35_Py_IDENTIFIER(stderr);
36
Victor Stinner024e37a2011-03-31 01:31:06 +020037#ifdef HAVE_SIGACTION
38typedef struct sigaction _Py_sighandler_t;
39#else
40typedef PyOS_sighandler_t _Py_sighandler_t;
41#endif
42
43typedef struct {
44 int signum;
45 int enabled;
46 const char* name;
47 _Py_sighandler_t previous;
48 int all_threads;
49} fault_handler_t;
50
51static struct {
52 int enabled;
53 PyObject *file;
54 int fd;
55 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020056 PyInterpreterState *interp;
Victor Stinner46c2b812017-04-21 18:06:13 +020057#ifdef MS_WINDOWS
58 void *exc_handler;
59#endif
Victor Stinner024e37a2011-03-31 01:31:06 +020060} fatal_error = {0, NULL, -1, 0};
61
Victor Stinner024e37a2011-03-31 01:31:06 +020062static struct {
63 PyObject *file;
64 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020065 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020066 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020067 PyInterpreterState *interp;
68 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020069 char *header;
70 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020071 /* The main thread always holds this lock. It is only released when
72 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020073 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020074 PyThread_type_lock cancel_event;
75 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020076 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020077} thread;
Victor Stinner024e37a2011-03-31 01:31:06 +020078
79#ifdef FAULTHANDLER_USER
80typedef struct {
81 int enabled;
82 PyObject *file;
83 int fd;
84 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020085 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020086 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020087 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020088} user_signal_t;
89
90static user_signal_t *user_signals;
91
92/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +020093#ifndef NSIG
94# if defined(_NSIG)
95# define NSIG _NSIG /* For BSD/SysV */
96# elif defined(_SIGMAX)
97# define NSIG (_SIGMAX + 1) /* For QNX */
98# elif defined(SIGMAX)
99# define NSIG (SIGMAX + 1) /* For djgpp */
100# else
101# define NSIG 64 /* Use a reasonable default value */
102# endif
103#endif
104
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200105static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200106#endif /* FAULTHANDLER_USER */
107
108
109static fault_handler_t faulthandler_handlers[] = {
110#ifdef SIGBUS
111 {SIGBUS, 0, "Bus error", },
112#endif
113#ifdef SIGILL
114 {SIGILL, 0, "Illegal instruction", },
115#endif
116 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200117 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200118 /* define SIGSEGV at the end to make it the default choice if searching the
119 handler fails in faulthandler_fatal_error() */
120 {SIGSEGV, 0, "Segmentation fault", }
121};
Victor Stinner404cdc52016-03-23 10:39:17 +0100122static const size_t faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200123 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200124
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100125/* Using an alternative stack requires sigaltstack()
126 and sigaction() SA_ONSTACK */
127#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
128# define FAULTHANDLER_USE_ALT_STACK
129#endif
130
131#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +0200132static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700133static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200134#endif
135
136
137/* Get the file descriptor of a file by calling its fileno() method and then
138 call its flush() method.
139
140 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100141 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200142
Victor Stinner95bb7142015-03-12 15:32:03 +0100143 On success, return the file descriptor and write the new file into *file_ptr.
144 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200145
Victor Stinner95bb7142015-03-12 15:32:03 +0100146static int
147faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200148{
149 PyObject *result;
150 long fd_long;
151 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100152 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200153
154 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100155 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200156 if (file == NULL) {
157 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100158 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200159 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200160 if (file == Py_None) {
161 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100162 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200163 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200164 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100165 else if (PyLong_Check(file)) {
166 fd = _PyLong_AsInt(file);
167 if (fd == -1 && PyErr_Occurred())
168 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700169 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100170 PyErr_SetString(PyExc_ValueError,
171 "file is not a valid file descripter");
172 return -1;
173 }
174 *file_ptr = NULL;
175 return fd;
176 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200177
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200178 result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno);
Victor Stinner024e37a2011-03-31 01:31:06 +0200179 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100180 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200181
182 fd = -1;
183 if (PyLong_Check(result)) {
184 fd_long = PyLong_AsLong(result);
185 if (0 <= fd_long && fd_long < INT_MAX)
186 fd = (int)fd_long;
187 }
188 Py_DECREF(result);
189
190 if (fd == -1) {
191 PyErr_SetString(PyExc_RuntimeError,
192 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100193 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200194 }
195
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200196 result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200197 if (result != NULL)
198 Py_DECREF(result);
199 else {
200 /* ignore flush() error */
201 PyErr_Clear();
202 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100203 *file_ptr = file;
204 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200205}
206
Victor Stinnera4de6d82011-04-09 00:47:23 +0200207/* Get the state of the current thread: only call this function if the current
208 thread holds the GIL. Raise an exception on error. */
209static PyThreadState*
210get_thread_state(void)
211{
Victor Stinner5592f2b2021-02-19 13:21:28 +0100212 PyThreadState *tstate = _PyThreadState_GET();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200213 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100214 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200215 PyErr_SetString(PyExc_RuntimeError,
216 "unable to get the current thread state");
217 return NULL;
218 }
219 return tstate;
220}
221
Victor Stinnerc7489a52015-04-01 18:48:58 +0200222static void
223faulthandler_dump_traceback(int fd, int all_threads,
224 PyInterpreterState *interp)
225{
226 static volatile int reentrant = 0;
227 PyThreadState *tstate;
228
229 if (reentrant)
230 return;
231
232 reentrant = 1;
233
Victor Stinnerc7489a52015-04-01 18:48:58 +0200234 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
235 are thus delivered to the thread that caused the fault. Get the Python
236 thread state of the current thread.
237
238 PyThreadState_Get() doesn't give the state of the thread that caused the
239 fault if the thread released the GIL, and so this function cannot be
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900240 used. Read the thread specific storage (TSS) instead: call
Victor Stinnerc7489a52015-04-01 18:48:58 +0200241 PyGILState_GetThisThreadState(). */
242 tstate = PyGILState_GetThisThreadState();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200243
Victor Stinner861d9ab2016-03-16 22:45:24 +0100244 if (all_threads) {
245 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
246 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200247 else {
248 if (tstate != NULL)
249 _Py_DumpTraceback(fd, tstate);
250 }
251
252 reentrant = 0;
253}
254
Victor Stinner024e37a2011-03-31 01:31:06 +0200255static PyObject*
256faulthandler_dump_traceback_py(PyObject *self,
257 PyObject *args, PyObject *kwargs)
258{
259 static char *kwlist[] = {"file", "all_threads", NULL};
260 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200261 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200262 PyThreadState *tstate;
263 const char *errmsg;
264 int fd;
265
266 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
267 "|Oi:dump_traceback", kwlist,
268 &file, &all_threads))
269 return NULL;
270
Victor Stinner95bb7142015-03-12 15:32:03 +0100271 fd = faulthandler_get_fileno(&file);
272 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200273 return NULL;
274
Victor Stinnera4de6d82011-04-09 00:47:23 +0200275 tstate = get_thread_state();
276 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200277 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200278
279 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100280 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200281 if (errmsg != NULL) {
282 PyErr_SetString(PyExc_RuntimeError, errmsg);
283 return NULL;
284 }
285 }
286 else {
287 _Py_DumpTraceback(fd, tstate);
288 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200289
290 if (PyErr_CheckSignals())
291 return NULL;
292
Victor Stinner024e37a2011-03-31 01:31:06 +0200293 Py_RETURN_NONE;
294}
295
Victor Stinner404cdc52016-03-23 10:39:17 +0100296static void
297faulthandler_disable_fatal_handler(fault_handler_t *handler)
298{
299 if (!handler->enabled)
300 return;
301 handler->enabled = 0;
302#ifdef HAVE_SIGACTION
303 (void)sigaction(handler->signum, &handler->previous, NULL);
304#else
305 (void)signal(handler->signum, handler->previous);
306#endif
307}
308
Victor Stinner024e37a2011-03-31 01:31:06 +0200309
Victor Stinner410dd7d2011-05-11 20:56:08 +0200310/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200311
312 Display the current Python traceback, restore the previous handler and call
313 the previous handler.
314
Victor Stinner410dd7d2011-05-11 20:56:08 +0200315 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200316 signal handler would not be called (for an unknown reason). The execution of
317 the program continues at faulthandler_fatal_error() exit, but the same
318 instruction will raise the same fault (signal), and so the previous handler
319 will be called.
320
Victor Stinner410dd7d2011-05-11 20:56:08 +0200321 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200322
323static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200324faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200325{
326 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100327 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200328 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200329 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200330
331 if (!fatal_error.enabled)
332 return;
333
334 for (i=0; i < faulthandler_nsignals; i++) {
335 handler = &faulthandler_handlers[i];
336 if (handler->signum == signum)
337 break;
338 }
339 if (handler == NULL) {
340 /* faulthandler_nsignals == 0 (unlikely) */
341 return;
342 }
343
344 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100345 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200346
347 PUTS(fd, "Fatal Python error: ");
348 PUTS(fd, handler->name);
349 PUTS(fd, "\n\n");
350
Victor Stinnerc7489a52015-04-01 18:48:58 +0200351 faulthandler_dump_traceback(fd, fatal_error.all_threads,
352 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200353
Victor Stinner250035d2021-01-18 20:47:13 +0100354 _Py_DumpExtensionModules(fd, fatal_error.interp);
355
Victor Stinnerc9256172011-05-07 12:20:11 +0200356 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200357#ifdef MS_WINDOWS
358 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200359 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200360 handler, because the Windows signal handler would not be called */
361 return;
362 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200363#endif
R David Murrayfc069992013-12-13 20:52:19 -0500364 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200365 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
366 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200367}
368
Victor Stinner404cdc52016-03-23 10:39:17 +0100369#ifdef MS_WINDOWS
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700370static int
371faulthandler_ignore_exception(DWORD code)
372{
373 /* bpo-30557: ignore exceptions which are not errors */
374 if (!(code & 0x80000000)) {
375 return 1;
376 }
377 /* bpo-31701: ignore MSC and COM exceptions
378 E0000000 + code */
379 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
380 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
381 return 1;
382 }
383 /* Interesting exception: log it with the Python traceback */
384 return 0;
385}
386
Victor Stinner404cdc52016-03-23 10:39:17 +0100387static LONG WINAPI
388faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
389{
390 const int fd = fatal_error.fd;
391 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100392 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100393
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700394 if (faulthandler_ignore_exception(code)) {
395 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100396 return EXCEPTION_CONTINUE_SEARCH;
397 }
398
399 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100400 switch (code)
401 {
402 /* only format most common errors */
403 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
404 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
405 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
406 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
407 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
408 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
409 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
410 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700411 PUTS(fd, "code 0x");
412 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100413 }
414 PUTS(fd, "\n\n");
415
416 if (code == EXCEPTION_ACCESS_VIOLATION) {
417 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200418 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100419 fault_handler_t *handler = &faulthandler_handlers[i];
420 if (handler->signum == SIGSEGV) {
421 faulthandler_disable_fatal_handler(handler);
422 break;
423 }
424 }
425 }
426
427 faulthandler_dump_traceback(fd, fatal_error.all_threads,
428 fatal_error.interp);
429
430 /* call the next exception handler */
431 return EXCEPTION_CONTINUE_SEARCH;
432}
433#endif
434
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100435
436#ifdef FAULTHANDLER_USE_ALT_STACK
437static int
438faulthandler_allocate_stack(void)
439{
440 if (stack.ss_sp != NULL) {
441 return 0;
442 }
443 /* Allocate an alternate stack for faulthandler() signal handler
444 to be able to execute a signal handler on a stack overflow error */
445 stack.ss_sp = PyMem_Malloc(stack.ss_size);
446 if (stack.ss_sp == NULL) {
447 PyErr_NoMemory();
448 return -1;
449 }
450
451 int err = sigaltstack(&stack, &old_stack);
452 if (err) {
453 /* Release the stack to retry sigaltstack() next time */
454 PyMem_Free(stack.ss_sp);
455 stack.ss_sp = NULL;
456
457 PyErr_SetFromErrno(PyExc_OSError);
458 return -1;
459 }
460 return 0;
461}
462#endif
463
464
Victor Stinnerd727e232011-04-01 12:13:55 +0200465/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200466
doko@ubuntu.combc731502016-05-18 01:06:01 +0200467static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100468faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200469{
Victor Stinner404cdc52016-03-23 10:39:17 +0100470 if (fatal_error.enabled) {
471 return 0;
472 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100473 fatal_error.enabled = 1;
474
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100475#ifdef FAULTHANDLER_USE_ALT_STACK
476 if (faulthandler_allocate_stack() < 0) {
477 return -1;
478 }
479#endif
480
Victor Stinner46c2b812017-04-21 18:06:13 +0200481 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100482 fault_handler_t *handler;
Victor Stinner928ad282016-03-23 15:19:12 +0100483 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100484
Victor Stinner928ad282016-03-23 15:19:12 +0100485 handler = &faulthandler_handlers[i];
486 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100487#ifdef HAVE_SIGACTION
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100488 struct sigaction action;
Victor Stinner404cdc52016-03-23 10:39:17 +0100489 action.sa_handler = faulthandler_fatal_error;
490 sigemptyset(&action.sa_mask);
491 /* Do not prevent the signal from being received from within
492 its own signal handler */
493 action.sa_flags = SA_NODEFER;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100494#ifdef FAULTHANDLER_USE_ALT_STACK
495 assert(stack.ss_sp != NULL);
496 /* Call the signal handler on an alternate signal stack
497 provided by sigaltstack() */
498 action.sa_flags |= SA_ONSTACK;
Victor Stinner404cdc52016-03-23 10:39:17 +0100499#endif
500 err = sigaction(handler->signum, &action, &handler->previous);
501#else
502 handler->previous = signal(handler->signum,
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100503 faulthandler_fatal_error);
Victor Stinner404cdc52016-03-23 10:39:17 +0100504 err = (handler->previous == SIG_ERR);
505#endif
506 if (err) {
507 PyErr_SetFromErrno(PyExc_RuntimeError);
508 return -1;
509 }
510
511 handler->enabled = 1;
512 }
513
514#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200515 assert(fatal_error.exc_handler == NULL);
516 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100517#endif
518 return 0;
519}
520
521static PyObject*
522faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
523{
524 static char *kwlist[] = {"file", "all_threads", NULL};
525 PyObject *file = NULL;
526 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200527 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200528 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200529
530 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
531 "|Oi:enable", kwlist, &file, &all_threads))
532 return NULL;
533
Victor Stinner95bb7142015-03-12 15:32:03 +0100534 fd = faulthandler_get_fileno(&file);
535 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200536 return NULL;
537
Victor Stinnera4de6d82011-04-09 00:47:23 +0200538 tstate = get_thread_state();
539 if (tstate == NULL)
540 return NULL;
541
Victor Stinner95bb7142015-03-12 15:32:03 +0100542 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300543 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200544 fatal_error.fd = fd;
545 fatal_error.all_threads = all_threads;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100546 fatal_error.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200547
Victor Stinner404cdc52016-03-23 10:39:17 +0100548 if (faulthandler_enable() < 0) {
549 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200550 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100551
Victor Stinner024e37a2011-03-31 01:31:06 +0200552 Py_RETURN_NONE;
553}
554
555static void
556faulthandler_disable(void)
557{
Victor Stinner024e37a2011-03-31 01:31:06 +0200558 if (fatal_error.enabled) {
559 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200560 for (size_t i=0; i < faulthandler_nsignals; i++) {
561 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200562 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100563 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200564 }
565 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200566#ifdef MS_WINDOWS
567 if (fatal_error.exc_handler != NULL) {
568 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
569 fatal_error.exc_handler = NULL;
570 }
571#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200572 Py_CLEAR(fatal_error.file);
573}
574
575static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530576faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200577{
578 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200579 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200580 }
581 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200582 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200583}
584
585static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530586faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200587{
588 return PyBool_FromLong(fatal_error.enabled);
589}
590
Victor Stinner024e37a2011-03-31 01:31:06 +0200591static void
592faulthandler_thread(void *unused)
593{
594 PyLockStatus st;
595 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200596 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200597#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200598 sigset_t set;
599
600 /* we don't want to receive any signal */
601 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200602 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200603#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200604
605 do {
606 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200607 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200608 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200609 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200610 break;
611 }
612 /* Timeout => dump traceback */
613 assert(st == PY_LOCK_FAILURE);
614
Victor Stinnerc7489a52015-04-01 18:48:58 +0200615 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200616
Victor Stinner861d9ab2016-03-16 22:45:24 +0100617 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200618 ok = (errmsg == NULL);
619
620 if (thread.exit)
621 _exit(1);
622 } while (ok && thread.repeat);
623
624 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200625 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200626}
627
628static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200629cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200630{
Thomas A Caswelle2783352019-08-29 12:30:04 -0400631 /* If not scheduled, nothing to cancel */
632 if (!thread.cancel_event) {
633 return;
634 }
635
Victor Stinner410dd7d2011-05-11 20:56:08 +0200636 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200637 PyThread_release_lock(thread.cancel_event);
638
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200639 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200640 PyThread_acquire_lock(thread.running, 1);
641 PyThread_release_lock(thread.running);
642
643 /* The main thread should always hold the cancel_event lock */
644 PyThread_acquire_lock(thread.cancel_event, 1);
645
Victor Stinner024e37a2011-03-31 01:31:06 +0200646 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200647 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200648 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200649 thread.header = NULL;
650 }
651}
652
Victor Stinner93fd4782017-10-27 07:27:12 -0700653#define SEC_TO_US (1000 * 1000)
654
Victor Stinnerc790a532011-04-08 13:39:59 +0200655static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700656format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200657{
Victor Stinner93fd4782017-10-27 07:27:12 -0700658 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200659 char buffer[100];
660
Victor Stinner93fd4782017-10-27 07:27:12 -0700661 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
662 sec = (unsigned long)(us / SEC_TO_US);
663 us %= SEC_TO_US;
664
Victor Stinnerc790a532011-04-08 13:39:59 +0200665 min = sec / 60;
666 sec %= 60;
667 hour = min / 60;
668 min %= 60;
669
Victor Stinner93fd4782017-10-27 07:27:12 -0700670 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200671 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700672 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
673 hour, min, sec, (unsigned int)us);
674 }
675 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200676 PyOS_snprintf(buffer, sizeof(buffer),
677 "Timeout (%lu:%02lu:%02lu)!\n",
678 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700679 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200680 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200681}
682
683static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200684faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200685 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200686{
687 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700688 PyObject *timeout_obj;
689 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200690 int repeat = 0;
691 PyObject *file = NULL;
692 int fd;
693 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200694 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200695 char *header;
696 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200697
698 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700699 "O|iOi:dump_traceback_later", kwlist,
700 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200701 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700702
703 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
704 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200705 return NULL;
706 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700707 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200708 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200709 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
710 return NULL;
711 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700712 /* Limit to LONG_MAX seconds for format_timeout() */
713 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
714 PyErr_SetString(PyExc_OverflowError,
715 "timeout value is too large");
716 return NULL;
717 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200718
Victor Stinnera4de6d82011-04-09 00:47:23 +0200719 tstate = get_thread_state();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100720 if (tstate == NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200721 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100722 }
Victor Stinner96994402011-04-07 11:37:19 +0200723
Victor Stinner95bb7142015-03-12 15:32:03 +0100724 fd = faulthandler_get_fileno(&file);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100725 if (fd < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200726 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100727 }
728
729 if (!thread.running) {
730 thread.running = PyThread_allocate_lock();
731 if (!thread.running) {
732 return PyErr_NoMemory();
733 }
734 }
735 if (!thread.cancel_event) {
736 thread.cancel_event = PyThread_allocate_lock();
737 if (!thread.cancel_event || !thread.running) {
738 return PyErr_NoMemory();
739 }
740
741 /* cancel_event starts to be acquired: it's only released to cancel
742 the thread. */
743 PyThread_acquire_lock(thread.cancel_event, 1);
744 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200745
Victor Stinnerc790a532011-04-08 13:39:59 +0200746 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700747 header = format_timeout(timeout_us);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100748 if (header == NULL) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200749 return PyErr_NoMemory();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100750 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200751 header_len = strlen(header);
752
Victor Stinner024e37a2011-03-31 01:31:06 +0200753 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200754 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200755
Victor Stinner95bb7142015-03-12 15:32:03 +0100756 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300757 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200758 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700759 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
760 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200761 thread.repeat = repeat;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100762 thread.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200763 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200764 thread.header = header;
765 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200766
767 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200768 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200769
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200770 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200771 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200772 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200773 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200774 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200775 PyErr_SetString(PyExc_RuntimeError,
776 "unable to start watchdog thread");
777 return NULL;
778 }
779
780 Py_RETURN_NONE;
781}
782
783static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530784faulthandler_cancel_dump_traceback_later_py(PyObject *self,
785 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200786{
Georg Brandldeb92b52012-09-22 08:58:55 +0200787 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200788 Py_RETURN_NONE;
789}
Victor Stinner024e37a2011-03-31 01:31:06 +0200790
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100791
Victor Stinner024e37a2011-03-31 01:31:06 +0200792#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200793static int
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100794faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200795{
796#ifdef HAVE_SIGACTION
797 struct sigaction action;
798 action.sa_handler = faulthandler_user;
799 sigemptyset(&action.sa_mask);
800 /* if the signal is received while the kernel is executing a system
801 call, try to restart the system call instead of interrupting it and
802 return EINTR. */
803 action.sa_flags = SA_RESTART;
804 if (chain) {
805 /* do not prevent the signal from being received from within its
806 own signal handler */
807 action.sa_flags = SA_NODEFER;
808 }
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100809#ifdef FAULTHANDLER_USE_ALT_STACK
810 assert(stack.ss_sp != NULL);
811 /* Call the signal handler on an alternate signal stack
812 provided by sigaltstack() */
813 action.sa_flags |= SA_ONSTACK;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200814#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100815 return sigaction(signum, &action, previous_p);
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200816#else
817 _Py_sighandler_t previous;
818 previous = signal(signum, faulthandler_user);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100819 if (previous_p != NULL) {
820 *previous_p = previous;
821 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200822 return (previous == SIG_ERR);
823#endif
824}
825
Victor Stinner024e37a2011-03-31 01:31:06 +0200826/* Handler of user signals (e.g. SIGUSR1).
827
828 Dump the traceback of the current thread, or of all threads if
829 thread.all_threads is true.
830
831 This function is signal safe and should only call signal safe functions. */
832
833static void
834faulthandler_user(int signum)
835{
836 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200837 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200838
839 user = &user_signals[signum];
840 if (!user->enabled)
841 return;
842
Victor Stinnerc7489a52015-04-01 18:48:58 +0200843 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200844
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200845#ifdef HAVE_SIGACTION
846 if (user->chain) {
847 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200848 errno = save_errno;
849
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200850 /* call the previous signal handler */
851 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200852
853 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200854 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200855 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200856 }
857#else
858 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200859 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200860 /* call the previous signal handler */
861 user->previous(signum);
862 }
863#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200864}
865
866static int
867check_signum(int signum)
868{
Victor Stinner46c2b812017-04-21 18:06:13 +0200869 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200870 if (faulthandler_handlers[i].signum == signum) {
871 PyErr_Format(PyExc_RuntimeError,
872 "signal %i cannot be registered, "
873 "use enable() instead",
874 signum);
875 return 0;
876 }
877 }
878 if (signum < 1 || NSIG <= signum) {
879 PyErr_SetString(PyExc_ValueError, "signal number out of range");
880 return 0;
881 }
882 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200883}
884
885static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200886faulthandler_register_py(PyObject *self,
887 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200888{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200889 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200890 int signum;
891 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200892 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200893 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200894 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200895 user_signal_t *user;
896 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200897 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200898 int err;
899
900 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200901 "i|Oii:register", kwlist,
902 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200903 return NULL;
904
Victor Stinner44378d42011-04-01 15:37:12 +0200905 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200906 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200907
Victor Stinnera4de6d82011-04-09 00:47:23 +0200908 tstate = get_thread_state();
909 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200910 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200911
Victor Stinner95bb7142015-03-12 15:32:03 +0100912 fd = faulthandler_get_fileno(&file);
913 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200914 return NULL;
915
916 if (user_signals == NULL) {
Andy Lester7668a8b2020-03-24 23:26:44 -0500917 user_signals = PyMem_Calloc(NSIG, sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200918 if (user_signals == NULL)
919 return PyErr_NoMemory();
920 }
921 user = &user_signals[signum];
922
923 if (!user->enabled) {
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100924#ifdef FAULTHANDLER_USE_ALT_STACK
925 if (faulthandler_allocate_stack() < 0) {
926 return NULL;
927 }
928#endif
929
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200930 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200931 if (err) {
932 PyErr_SetFromErrno(PyExc_OSError);
933 return NULL;
934 }
Victor Stinner8d379542013-07-02 00:14:56 +0200935
936 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200937 }
938
Victor Stinner95bb7142015-03-12 15:32:03 +0100939 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300940 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200941 user->fd = fd;
942 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200943 user->chain = chain;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100944 user->interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200945 user->enabled = 1;
946
947 Py_RETURN_NONE;
948}
949
950static int
951faulthandler_unregister(user_signal_t *user, int signum)
952{
Victor Stinnera01ca122011-04-01 12:56:17 +0200953 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200954 return 0;
955 user->enabled = 0;
956#ifdef HAVE_SIGACTION
957 (void)sigaction(signum, &user->previous, NULL);
958#else
959 (void)signal(signum, user->previous);
960#endif
961 Py_CLEAR(user->file);
962 user->fd = -1;
963 return 1;
964}
965
966static PyObject*
967faulthandler_unregister_py(PyObject *self, PyObject *args)
968{
969 int signum;
970 user_signal_t *user;
971 int change;
972
973 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
974 return NULL;
975
Victor Stinner44378d42011-04-01 15:37:12 +0200976 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200977 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200978
Victor Stinnercfa71232011-04-08 12:48:15 +0200979 if (user_signals == NULL)
980 Py_RETURN_FALSE;
981
Victor Stinner024e37a2011-03-31 01:31:06 +0200982 user = &user_signals[signum];
983 change = faulthandler_unregister(user, signum);
984 return PyBool_FromLong(change);
985}
986#endif /* FAULTHANDLER_USER */
987
988
Victor Stinner7a399122014-09-30 13:40:12 +0200989static void
990faulthandler_suppress_crash_report(void)
991{
992#ifdef MS_WINDOWS
993 UINT mode;
994
995 /* Configure Windows to not display the Windows Error Reporting dialog */
996 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
997 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
998#endif
999
1000#ifdef HAVE_SYS_RESOURCE_H
1001 struct rlimit rl;
1002
1003 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +01001004 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +02001005 rl.rlim_cur = 0;
1006 setrlimit(RLIMIT_CORE, &rl);
1007 }
1008#endif
1009
1010#ifdef _MSC_VER
1011 /* Visual Studio: configure abort() to not display an error message nor
1012 open a popup asking to report the fault. */
1013 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1014#endif
1015}
1016
Victor Stinner024e37a2011-03-31 01:31:06 +02001017static PyObject *
1018faulthandler_read_null(PyObject *self, PyObject *args)
1019{
Victor Stinnera2477202012-01-30 00:07:43 +01001020 volatile int *x;
1021 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +01001022
Victor Stinner7a399122014-09-30 13:40:12 +02001023 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +01001024 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +02001025 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +02001026 return PyLong_FromLong(y);
1027
1028}
1029
Victor Stinner50838282014-09-30 13:54:14 +02001030static void
1031faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +02001032{
Victor Stinner7a399122014-09-30 13:40:12 +02001033 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001034#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +02001035 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
1036 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +02001037 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +02001038 SIGSEGV was raised by the kernel because of a fault, and so if the
1039 program retries to execute the same instruction, the fault will be
1040 raised again.
1041
1042 Here the fault is simulated by a fake SIGSEGV signal raised by the
1043 application. We have to raise SIGSEGV at lease twice: once for
1044 faulthandler_fatal_error(), and one more time for the previous signal
1045 handler. */
1046 while(1)
1047 raise(SIGSEGV);
1048#else
1049 raise(SIGSEGV);
1050#endif
Victor Stinner50838282014-09-30 13:54:14 +02001051}
1052
1053static PyObject *
1054faulthandler_sigsegv(PyObject *self, PyObject *args)
1055{
1056 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +01001057 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +02001058 return NULL;
1059
1060 if (release_gil) {
1061 Py_BEGIN_ALLOW_THREADS
1062 faulthandler_raise_sigsegv();
1063 Py_END_ALLOW_THREADS
1064 } else {
1065 faulthandler_raise_sigsegv();
1066 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001067 Py_RETURN_NONE;
1068}
1069
Victor Stinner2a4903f2020-01-30 13:09:11 +01001070static void _Py_NO_RETURN
Victor Stinner861d9ab2016-03-16 22:45:24 +01001071faulthandler_fatal_error_thread(void *plock)
1072{
Victor Stinner861d9ab2016-03-16 22:45:24 +01001073 Py_FatalError("in new thread");
Victor Stinner861d9ab2016-03-16 22:45:24 +01001074}
1075
1076static PyObject *
1077faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1078{
1079 long thread;
1080 PyThread_type_lock lock;
1081
1082 faulthandler_suppress_crash_report();
1083
1084 lock = PyThread_allocate_lock();
1085 if (lock == NULL)
1086 return PyErr_NoMemory();
1087
1088 PyThread_acquire_lock(lock, WAIT_LOCK);
1089
1090 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1091 if (thread == -1) {
1092 PyThread_free_lock(lock);
1093 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1094 return NULL;
1095 }
1096
1097 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001098 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001099 PyThread_acquire_lock(lock, WAIT_LOCK);
1100 PyThread_release_lock(lock);
1101 PyThread_free_lock(lock);
1102
1103 Py_RETURN_NONE;
1104}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001105
Victor Stinner024e37a2011-03-31 01:31:06 +02001106static PyObject *
1107faulthandler_sigfpe(PyObject *self, PyObject *args)
1108{
1109 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1110 PowerPC. Use volatile to disable compile-time optimizations. */
1111 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001112 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001113 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001114 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1115 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001116 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001117 /* This line is never reached, but we pretend to make something with z
1118 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001119 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001120}
1121
Victor Stinnerd727e232011-04-01 12:13:55 +02001122static PyObject *
1123faulthandler_sigabrt(PyObject *self, PyObject *args)
1124{
Victor Stinner7a399122014-09-30 13:40:12 +02001125 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001126 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001127 Py_RETURN_NONE;
1128}
1129
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001130#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001131#define FAULTHANDLER_STACK_OVERFLOW
1132
Victor Stinner8b787962019-12-04 21:10:06 +01001133static uintptr_t
Benjamin Petersonca470632016-09-06 13:47:26 -07001134stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001135{
Victor Stinner8b787962019-12-04 21:10:06 +01001136 /* Allocate (at least) 4096 bytes on the stack at each call.
1137
1138 bpo-23654, bpo-38965: use volatile keyword to prevent tail call
1139 optimization. */
1140 volatile unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001141 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001142 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001143 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001144 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001145 buffer[0] = 1;
1146 buffer[4095] = 0;
1147 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001148}
1149
1150static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301151faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001152{
1153 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001154 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001155 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001156
Victor Stinner7a399122014-09-30 13:40:12 +02001157 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001158 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001159
1160 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1161 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1162 }
1163 else {
1164 lower_limit = 0;
1165 }
1166
1167 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1168 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1169 }
1170 else {
1171 upper_limit = UINTPTR_MAX;
1172 }
1173
1174 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001175 if (sp < stop)
1176 size = stop - sp;
1177 else
1178 size = sp - stop;
1179 PyErr_Format(PyExc_RuntimeError,
1180 "unable to raise a stack overflow (allocated %zu bytes "
1181 "on the stack, %zu recursive calls)",
1182 size, depth);
1183 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001184}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001185#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001186
1187
1188static int
1189faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1190{
Victor Stinner024e37a2011-03-31 01:31:06 +02001191 Py_VISIT(thread.file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001192#ifdef FAULTHANDLER_USER
1193 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001194 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001195 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001196 }
1197#endif
1198 Py_VISIT(fatal_error.file);
1199 return 0;
1200}
1201
Victor Stinner404cdc52016-03-23 10:39:17 +01001202#ifdef MS_WINDOWS
1203static PyObject *
1204faulthandler_raise_exception(PyObject *self, PyObject *args)
1205{
1206 unsigned int code, flags = 0;
1207 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1208 return NULL;
1209 faulthandler_suppress_crash_report();
1210 RaiseException(code, flags, 0, NULL);
1211 Py_RETURN_NONE;
1212}
1213#endif
1214
Victor Stinner024e37a2011-03-31 01:31:06 +02001215PyDoc_STRVAR(module_doc,
1216"faulthandler module.");
1217
1218static PyMethodDef module_methods[] = {
1219 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001220 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001221 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001222 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301223 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001224 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301225 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001226 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1227 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001228 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001229 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001230 "dump the traceback of the current thread, or of all threads "
1231 "if all_threads is True, into file")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001232 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001233 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001234 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001235 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001236 "or each timeout seconds if repeat is True. If exit is True, "
1237 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001238 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301239 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001240 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1241 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001242#ifdef FAULTHANDLER_USER
1243 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001244 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001245 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001246 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001247 "traceback of the current thread, or of all threads if "
1248 "all_threads is True, into file")},
1249 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001250 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001251 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1252 "'signum' registered by register()")},
1253#endif
Victor Stinner50838282014-09-30 13:54:14 +02001254 {"_read_null", faulthandler_read_null, METH_NOARGS,
1255 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001256 "a SIGSEGV or SIGBUS signal depending on the platform")},
1257 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001258 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001259 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1260 PyDoc_STR("fatal_error_c_thread(): "
1261 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001262 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001263 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001264 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1265 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001266#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301267 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001268 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1269#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001270#ifdef MS_WINDOWS
1271 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1272 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1273#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001274 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001275};
1276
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001277static int
1278PyExec_faulthandler(PyObject *module) {
1279 /* Add constants for unit tests */
1280#ifdef MS_WINDOWS
1281 /* RaiseException() codes (prefixed by an underscore) */
1282 if (PyModule_AddIntConstant(module, "_EXCEPTION_ACCESS_VIOLATION",
1283 EXCEPTION_ACCESS_VIOLATION)) {
1284 return -1;
1285 }
1286 if (PyModule_AddIntConstant(module, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1287 EXCEPTION_INT_DIVIDE_BY_ZERO)) {
1288 return -1;
1289 }
1290 if (PyModule_AddIntConstant(module, "_EXCEPTION_STACK_OVERFLOW",
1291 EXCEPTION_STACK_OVERFLOW)) {
1292 return -1;
1293 }
1294
1295 /* RaiseException() flags (prefixed by an underscore) */
1296 if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE",
1297 EXCEPTION_NONCONTINUABLE)) {
1298 return -1;
1299 }
1300 if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1301 EXCEPTION_NONCONTINUABLE_EXCEPTION)) {
1302 return -1;
1303 }
1304#endif
1305 return 0;
1306}
1307
1308static PyModuleDef_Slot faulthandler_slots[] = {
1309 {Py_mod_exec, PyExec_faulthandler},
1310 {0, NULL}
1311};
1312
Victor Stinner024e37a2011-03-31 01:31:06 +02001313static struct PyModuleDef module_def = {
1314 PyModuleDef_HEAD_INIT,
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001315 .m_name = "faulthandler",
1316 .m_doc = module_doc,
1317 .m_methods = module_methods,
1318 .m_traverse = faulthandler_traverse,
1319 .m_slots = faulthandler_slots
Victor Stinner024e37a2011-03-31 01:31:06 +02001320};
1321
1322PyMODINIT_FUNC
1323PyInit_faulthandler(void)
1324{
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001325 return PyModuleDef_Init(&module_def);
Victor Stinner024e37a2011-03-31 01:31:06 +02001326}
1327
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001328static int
1329faulthandler_init_enable(void)
1330{
1331 PyObject *module = PyImport_ImportModule("faulthandler");
1332 if (module == NULL) {
1333 return -1;
1334 }
1335
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001336 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001337 Py_DECREF(module);
1338 if (res == NULL) {
1339 return -1;
1340 }
1341 Py_DECREF(res);
1342
1343 return 0;
1344}
1345
Victor Stinner331a6a52019-05-27 16:39:22 +02001346PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001347_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001348{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001349#ifdef FAULTHANDLER_USE_ALT_STACK
1350 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001351 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001352 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1353 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1354 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1355 platforms. */
1356 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001357#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001358
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001359 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001360
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001361 if (enable) {
1362 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001363 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001364 }
1365 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001366 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001367}
1368
1369void _PyFaulthandler_Fini(void)
1370{
Victor Stinner024e37a2011-03-31 01:31:06 +02001371 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001372 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001373 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001374 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001375 PyThread_free_lock(thread.cancel_event);
1376 thread.cancel_event = NULL;
1377 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001378 if (thread.running) {
1379 PyThread_free_lock(thread.running);
1380 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001381 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001382
1383#ifdef FAULTHANDLER_USER
1384 /* user */
1385 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001386 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001387 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001388 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001389 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001390 user_signals = NULL;
1391 }
1392#endif
1393
1394 /* fatal */
1395 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001396
1397#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001398 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001399 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001400 stack_t current_stack;
1401 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001402 if (sigaltstack(NULL, &current_stack) == 0) {
1403 if (current_stack.ss_sp == stack.ss_sp) {
1404 /* The current alt stack is the one that we installed.
1405 It is safe to restore the old stack that we found when
1406 we installed ours */
1407 sigaltstack(&old_stack, NULL);
1408 } else {
1409 /* Someone switched to a different alt stack and didn't
1410 restore ours when they were done (if they're done).
1411 There's not much we can do in this unlikely case */
1412 }
1413 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001414 PyMem_Free(stack.ss_sp);
1415 stack.ss_sp = NULL;
1416 }
1417#endif
1418}