blob: da8b7741345de05c27e3f494dc7730988acf517c [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 Stinnere2320252021-01-18 18:24:29 +01004#include "pycore_traceback.h" // _Py_DumpTracebackThreads
Victor Stinner024e37a2011-03-31 01:31:06 +02005#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 Stinner250035d2021-01-18 20:47:13 +0100353 _Py_DumpExtensionModules(fd, fatal_error.interp);
354
Victor Stinnerc9256172011-05-07 12:20:11 +0200355 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200356#ifdef MS_WINDOWS
357 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200358 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200359 handler, because the Windows signal handler would not be called */
360 return;
361 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200362#endif
R David Murrayfc069992013-12-13 20:52:19 -0500363 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200364 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
365 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200366}
367
Victor Stinner404cdc52016-03-23 10:39:17 +0100368#ifdef MS_WINDOWS
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700369static int
370faulthandler_ignore_exception(DWORD code)
371{
372 /* bpo-30557: ignore exceptions which are not errors */
373 if (!(code & 0x80000000)) {
374 return 1;
375 }
376 /* bpo-31701: ignore MSC and COM exceptions
377 E0000000 + code */
378 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
379 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
380 return 1;
381 }
382 /* Interesting exception: log it with the Python traceback */
383 return 0;
384}
385
Victor Stinner404cdc52016-03-23 10:39:17 +0100386static LONG WINAPI
387faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
388{
389 const int fd = fatal_error.fd;
390 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100391 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100392
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700393 if (faulthandler_ignore_exception(code)) {
394 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100395 return EXCEPTION_CONTINUE_SEARCH;
396 }
397
398 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100399 switch (code)
400 {
401 /* only format most common errors */
402 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
403 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
404 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
405 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
406 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
407 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
408 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
409 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700410 PUTS(fd, "code 0x");
411 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100412 }
413 PUTS(fd, "\n\n");
414
415 if (code == EXCEPTION_ACCESS_VIOLATION) {
416 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200417 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100418 fault_handler_t *handler = &faulthandler_handlers[i];
419 if (handler->signum == SIGSEGV) {
420 faulthandler_disable_fatal_handler(handler);
421 break;
422 }
423 }
424 }
425
426 faulthandler_dump_traceback(fd, fatal_error.all_threads,
427 fatal_error.interp);
428
429 /* call the next exception handler */
430 return EXCEPTION_CONTINUE_SEARCH;
431}
432#endif
433
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100434
435#ifdef FAULTHANDLER_USE_ALT_STACK
436static int
437faulthandler_allocate_stack(void)
438{
439 if (stack.ss_sp != NULL) {
440 return 0;
441 }
442 /* Allocate an alternate stack for faulthandler() signal handler
443 to be able to execute a signal handler on a stack overflow error */
444 stack.ss_sp = PyMem_Malloc(stack.ss_size);
445 if (stack.ss_sp == NULL) {
446 PyErr_NoMemory();
447 return -1;
448 }
449
450 int err = sigaltstack(&stack, &old_stack);
451 if (err) {
452 /* Release the stack to retry sigaltstack() next time */
453 PyMem_Free(stack.ss_sp);
454 stack.ss_sp = NULL;
455
456 PyErr_SetFromErrno(PyExc_OSError);
457 return -1;
458 }
459 return 0;
460}
461#endif
462
463
Victor Stinnerd727e232011-04-01 12:13:55 +0200464/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200465
doko@ubuntu.combc731502016-05-18 01:06:01 +0200466static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100467faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200468{
Victor Stinner404cdc52016-03-23 10:39:17 +0100469 if (fatal_error.enabled) {
470 return 0;
471 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100472 fatal_error.enabled = 1;
473
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100474#ifdef FAULTHANDLER_USE_ALT_STACK
475 if (faulthandler_allocate_stack() < 0) {
476 return -1;
477 }
478#endif
479
Victor Stinner46c2b812017-04-21 18:06:13 +0200480 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100481 fault_handler_t *handler;
Victor Stinner928ad282016-03-23 15:19:12 +0100482 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100483
Victor Stinner928ad282016-03-23 15:19:12 +0100484 handler = &faulthandler_handlers[i];
485 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100486#ifdef HAVE_SIGACTION
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100487 struct sigaction action;
Victor Stinner404cdc52016-03-23 10:39:17 +0100488 action.sa_handler = faulthandler_fatal_error;
489 sigemptyset(&action.sa_mask);
490 /* Do not prevent the signal from being received from within
491 its own signal handler */
492 action.sa_flags = SA_NODEFER;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100493#ifdef FAULTHANDLER_USE_ALT_STACK
494 assert(stack.ss_sp != NULL);
495 /* Call the signal handler on an alternate signal stack
496 provided by sigaltstack() */
497 action.sa_flags |= SA_ONSTACK;
Victor Stinner404cdc52016-03-23 10:39:17 +0100498#endif
499 err = sigaction(handler->signum, &action, &handler->previous);
500#else
501 handler->previous = signal(handler->signum,
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100502 faulthandler_fatal_error);
Victor Stinner404cdc52016-03-23 10:39:17 +0100503 err = (handler->previous == SIG_ERR);
504#endif
505 if (err) {
506 PyErr_SetFromErrno(PyExc_RuntimeError);
507 return -1;
508 }
509
510 handler->enabled = 1;
511 }
512
513#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200514 assert(fatal_error.exc_handler == NULL);
515 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100516#endif
517 return 0;
518}
519
520static PyObject*
521faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
522{
523 static char *kwlist[] = {"file", "all_threads", NULL};
524 PyObject *file = NULL;
525 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200526 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200527 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200528
529 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
530 "|Oi:enable", kwlist, &file, &all_threads))
531 return NULL;
532
Victor Stinner95bb7142015-03-12 15:32:03 +0100533 fd = faulthandler_get_fileno(&file);
534 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200535 return NULL;
536
Victor Stinnera4de6d82011-04-09 00:47:23 +0200537 tstate = get_thread_state();
538 if (tstate == NULL)
539 return NULL;
540
Victor Stinner95bb7142015-03-12 15:32:03 +0100541 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300542 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200543 fatal_error.fd = fd;
544 fatal_error.all_threads = all_threads;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100545 fatal_error.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200546
Victor Stinner404cdc52016-03-23 10:39:17 +0100547 if (faulthandler_enable() < 0) {
548 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200549 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100550
Victor Stinner024e37a2011-03-31 01:31:06 +0200551 Py_RETURN_NONE;
552}
553
554static void
555faulthandler_disable(void)
556{
Victor Stinner024e37a2011-03-31 01:31:06 +0200557 if (fatal_error.enabled) {
558 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200559 for (size_t i=0; i < faulthandler_nsignals; i++) {
560 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200561 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100562 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200563 }
564 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200565#ifdef MS_WINDOWS
566 if (fatal_error.exc_handler != NULL) {
567 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
568 fatal_error.exc_handler = NULL;
569 }
570#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200571 Py_CLEAR(fatal_error.file);
572}
573
574static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530575faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200576{
577 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200578 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200579 }
580 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200581 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200582}
583
584static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530585faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200586{
587 return PyBool_FromLong(fatal_error.enabled);
588}
589
Victor Stinner024e37a2011-03-31 01:31:06 +0200590static void
591faulthandler_thread(void *unused)
592{
593 PyLockStatus st;
594 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200595 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200596#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200597 sigset_t set;
598
599 /* we don't want to receive any signal */
600 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200601 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200602#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200603
604 do {
605 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200606 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200607 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200608 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200609 break;
610 }
611 /* Timeout => dump traceback */
612 assert(st == PY_LOCK_FAILURE);
613
Victor Stinnerc7489a52015-04-01 18:48:58 +0200614 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200615
Victor Stinner861d9ab2016-03-16 22:45:24 +0100616 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200617 ok = (errmsg == NULL);
618
619 if (thread.exit)
620 _exit(1);
621 } while (ok && thread.repeat);
622
623 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200624 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200625}
626
627static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200628cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200629{
Thomas A Caswelle2783352019-08-29 12:30:04 -0400630 /* If not scheduled, nothing to cancel */
631 if (!thread.cancel_event) {
632 return;
633 }
634
Victor Stinner410dd7d2011-05-11 20:56:08 +0200635 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200636 PyThread_release_lock(thread.cancel_event);
637
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200638 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200639 PyThread_acquire_lock(thread.running, 1);
640 PyThread_release_lock(thread.running);
641
642 /* The main thread should always hold the cancel_event lock */
643 PyThread_acquire_lock(thread.cancel_event, 1);
644
Victor Stinner024e37a2011-03-31 01:31:06 +0200645 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200646 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200647 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200648 thread.header = NULL;
649 }
650}
651
Victor Stinner93fd4782017-10-27 07:27:12 -0700652#define SEC_TO_US (1000 * 1000)
653
Victor Stinnerc790a532011-04-08 13:39:59 +0200654static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700655format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200656{
Victor Stinner93fd4782017-10-27 07:27:12 -0700657 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200658 char buffer[100];
659
Victor Stinner93fd4782017-10-27 07:27:12 -0700660 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
661 sec = (unsigned long)(us / SEC_TO_US);
662 us %= SEC_TO_US;
663
Victor Stinnerc790a532011-04-08 13:39:59 +0200664 min = sec / 60;
665 sec %= 60;
666 hour = min / 60;
667 min %= 60;
668
Victor Stinner93fd4782017-10-27 07:27:12 -0700669 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200670 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700671 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
672 hour, min, sec, (unsigned int)us);
673 }
674 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200675 PyOS_snprintf(buffer, sizeof(buffer),
676 "Timeout (%lu:%02lu:%02lu)!\n",
677 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700678 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200679 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200680}
681
682static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200683faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200684 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200685{
686 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700687 PyObject *timeout_obj;
688 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200689 int repeat = 0;
690 PyObject *file = NULL;
691 int fd;
692 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200693 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200694 char *header;
695 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200696
697 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700698 "O|iOi:dump_traceback_later", kwlist,
699 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200700 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700701
702 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
703 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200704 return NULL;
705 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700706 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200707 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200708 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
709 return NULL;
710 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700711 /* Limit to LONG_MAX seconds for format_timeout() */
712 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
713 PyErr_SetString(PyExc_OverflowError,
714 "timeout value is too large");
715 return NULL;
716 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200717
Victor Stinnera4de6d82011-04-09 00:47:23 +0200718 tstate = get_thread_state();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100719 if (tstate == NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200720 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100721 }
Victor Stinner96994402011-04-07 11:37:19 +0200722
Victor Stinner95bb7142015-03-12 15:32:03 +0100723 fd = faulthandler_get_fileno(&file);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100724 if (fd < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200725 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100726 }
727
728 if (!thread.running) {
729 thread.running = PyThread_allocate_lock();
730 if (!thread.running) {
731 return PyErr_NoMemory();
732 }
733 }
734 if (!thread.cancel_event) {
735 thread.cancel_event = PyThread_allocate_lock();
736 if (!thread.cancel_event || !thread.running) {
737 return PyErr_NoMemory();
738 }
739
740 /* cancel_event starts to be acquired: it's only released to cancel
741 the thread. */
742 PyThread_acquire_lock(thread.cancel_event, 1);
743 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200744
Victor Stinnerc790a532011-04-08 13:39:59 +0200745 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700746 header = format_timeout(timeout_us);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100747 if (header == NULL) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200748 return PyErr_NoMemory();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100749 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200750 header_len = strlen(header);
751
Victor Stinner024e37a2011-03-31 01:31:06 +0200752 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200753 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200754
Victor Stinner95bb7142015-03-12 15:32:03 +0100755 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300756 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200757 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700758 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
759 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200760 thread.repeat = repeat;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100761 thread.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200762 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200763 thread.header = header;
764 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200765
766 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200767 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200768
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200769 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200770 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200771 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200772 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200773 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200774 PyErr_SetString(PyExc_RuntimeError,
775 "unable to start watchdog thread");
776 return NULL;
777 }
778
779 Py_RETURN_NONE;
780}
781
782static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530783faulthandler_cancel_dump_traceback_later_py(PyObject *self,
784 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200785{
Georg Brandldeb92b52012-09-22 08:58:55 +0200786 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200787 Py_RETURN_NONE;
788}
Victor Stinner024e37a2011-03-31 01:31:06 +0200789
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100790
Victor Stinner024e37a2011-03-31 01:31:06 +0200791#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200792static int
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100793faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200794{
795#ifdef HAVE_SIGACTION
796 struct sigaction action;
797 action.sa_handler = faulthandler_user;
798 sigemptyset(&action.sa_mask);
799 /* if the signal is received while the kernel is executing a system
800 call, try to restart the system call instead of interrupting it and
801 return EINTR. */
802 action.sa_flags = SA_RESTART;
803 if (chain) {
804 /* do not prevent the signal from being received from within its
805 own signal handler */
806 action.sa_flags = SA_NODEFER;
807 }
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100808#ifdef FAULTHANDLER_USE_ALT_STACK
809 assert(stack.ss_sp != NULL);
810 /* Call the signal handler on an alternate signal stack
811 provided by sigaltstack() */
812 action.sa_flags |= SA_ONSTACK;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200813#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100814 return sigaction(signum, &action, previous_p);
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200815#else
816 _Py_sighandler_t previous;
817 previous = signal(signum, faulthandler_user);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100818 if (previous_p != NULL) {
819 *previous_p = previous;
820 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200821 return (previous == SIG_ERR);
822#endif
823}
824
Victor Stinner024e37a2011-03-31 01:31:06 +0200825/* Handler of user signals (e.g. SIGUSR1).
826
827 Dump the traceback of the current thread, or of all threads if
828 thread.all_threads is true.
829
830 This function is signal safe and should only call signal safe functions. */
831
832static void
833faulthandler_user(int signum)
834{
835 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200836 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200837
838 user = &user_signals[signum];
839 if (!user->enabled)
840 return;
841
Victor Stinnerc7489a52015-04-01 18:48:58 +0200842 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200843
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200844#ifdef HAVE_SIGACTION
845 if (user->chain) {
846 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200847 errno = save_errno;
848
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200849 /* call the previous signal handler */
850 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200851
852 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200853 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200854 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200855 }
856#else
857 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200858 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200859 /* call the previous signal handler */
860 user->previous(signum);
861 }
862#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200863}
864
865static int
866check_signum(int signum)
867{
Victor Stinner46c2b812017-04-21 18:06:13 +0200868 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200869 if (faulthandler_handlers[i].signum == signum) {
870 PyErr_Format(PyExc_RuntimeError,
871 "signal %i cannot be registered, "
872 "use enable() instead",
873 signum);
874 return 0;
875 }
876 }
877 if (signum < 1 || NSIG <= signum) {
878 PyErr_SetString(PyExc_ValueError, "signal number out of range");
879 return 0;
880 }
881 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200882}
883
884static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200885faulthandler_register_py(PyObject *self,
886 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200887{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200888 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200889 int signum;
890 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200891 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200892 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200893 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200894 user_signal_t *user;
895 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200896 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200897 int err;
898
899 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200900 "i|Oii:register", kwlist,
901 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200902 return NULL;
903
Victor Stinner44378d42011-04-01 15:37:12 +0200904 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200905 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200906
Victor Stinnera4de6d82011-04-09 00:47:23 +0200907 tstate = get_thread_state();
908 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200909 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200910
Victor Stinner95bb7142015-03-12 15:32:03 +0100911 fd = faulthandler_get_fileno(&file);
912 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200913 return NULL;
914
915 if (user_signals == NULL) {
Andy Lester7668a8b2020-03-24 23:26:44 -0500916 user_signals = PyMem_Calloc(NSIG, sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200917 if (user_signals == NULL)
918 return PyErr_NoMemory();
919 }
920 user = &user_signals[signum];
921
922 if (!user->enabled) {
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100923#ifdef FAULTHANDLER_USE_ALT_STACK
924 if (faulthandler_allocate_stack() < 0) {
925 return NULL;
926 }
927#endif
928
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200929 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200930 if (err) {
931 PyErr_SetFromErrno(PyExc_OSError);
932 return NULL;
933 }
Victor Stinner8d379542013-07-02 00:14:56 +0200934
935 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200936 }
937
Victor Stinner95bb7142015-03-12 15:32:03 +0100938 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300939 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200940 user->fd = fd;
941 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200942 user->chain = chain;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100943 user->interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200944 user->enabled = 1;
945
946 Py_RETURN_NONE;
947}
948
949static int
950faulthandler_unregister(user_signal_t *user, int signum)
951{
Victor Stinnera01ca122011-04-01 12:56:17 +0200952 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200953 return 0;
954 user->enabled = 0;
955#ifdef HAVE_SIGACTION
956 (void)sigaction(signum, &user->previous, NULL);
957#else
958 (void)signal(signum, user->previous);
959#endif
960 Py_CLEAR(user->file);
961 user->fd = -1;
962 return 1;
963}
964
965static PyObject*
966faulthandler_unregister_py(PyObject *self, PyObject *args)
967{
968 int signum;
969 user_signal_t *user;
970 int change;
971
972 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
973 return NULL;
974
Victor Stinner44378d42011-04-01 15:37:12 +0200975 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200976 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200977
Victor Stinnercfa71232011-04-08 12:48:15 +0200978 if (user_signals == NULL)
979 Py_RETURN_FALSE;
980
Victor Stinner024e37a2011-03-31 01:31:06 +0200981 user = &user_signals[signum];
982 change = faulthandler_unregister(user, signum);
983 return PyBool_FromLong(change);
984}
985#endif /* FAULTHANDLER_USER */
986
987
Victor Stinner7a399122014-09-30 13:40:12 +0200988static void
989faulthandler_suppress_crash_report(void)
990{
991#ifdef MS_WINDOWS
992 UINT mode;
993
994 /* Configure Windows to not display the Windows Error Reporting dialog */
995 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
996 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
997#endif
998
999#ifdef HAVE_SYS_RESOURCE_H
1000 struct rlimit rl;
1001
1002 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +01001003 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +02001004 rl.rlim_cur = 0;
1005 setrlimit(RLIMIT_CORE, &rl);
1006 }
1007#endif
1008
1009#ifdef _MSC_VER
1010 /* Visual Studio: configure abort() to not display an error message nor
1011 open a popup asking to report the fault. */
1012 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1013#endif
1014}
1015
Victor Stinner024e37a2011-03-31 01:31:06 +02001016static PyObject *
1017faulthandler_read_null(PyObject *self, PyObject *args)
1018{
Victor Stinnera2477202012-01-30 00:07:43 +01001019 volatile int *x;
1020 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +01001021
Victor Stinner7a399122014-09-30 13:40:12 +02001022 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +01001023 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +02001024 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +02001025 return PyLong_FromLong(y);
1026
1027}
1028
Victor Stinner50838282014-09-30 13:54:14 +02001029static void
1030faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +02001031{
Victor Stinner7a399122014-09-30 13:40:12 +02001032 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001033#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +02001034 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
1035 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +02001036 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +02001037 SIGSEGV was raised by the kernel because of a fault, and so if the
1038 program retries to execute the same instruction, the fault will be
1039 raised again.
1040
1041 Here the fault is simulated by a fake SIGSEGV signal raised by the
1042 application. We have to raise SIGSEGV at lease twice: once for
1043 faulthandler_fatal_error(), and one more time for the previous signal
1044 handler. */
1045 while(1)
1046 raise(SIGSEGV);
1047#else
1048 raise(SIGSEGV);
1049#endif
Victor Stinner50838282014-09-30 13:54:14 +02001050}
1051
1052static PyObject *
1053faulthandler_sigsegv(PyObject *self, PyObject *args)
1054{
1055 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +01001056 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +02001057 return NULL;
1058
1059 if (release_gil) {
1060 Py_BEGIN_ALLOW_THREADS
1061 faulthandler_raise_sigsegv();
1062 Py_END_ALLOW_THREADS
1063 } else {
1064 faulthandler_raise_sigsegv();
1065 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001066 Py_RETURN_NONE;
1067}
1068
Victor Stinner2a4903f2020-01-30 13:09:11 +01001069static void _Py_NO_RETURN
Victor Stinner861d9ab2016-03-16 22:45:24 +01001070faulthandler_fatal_error_thread(void *plock)
1071{
Victor Stinner861d9ab2016-03-16 22:45:24 +01001072 Py_FatalError("in new thread");
Victor Stinner861d9ab2016-03-16 22:45:24 +01001073}
1074
1075static PyObject *
1076faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1077{
1078 long thread;
1079 PyThread_type_lock lock;
1080
1081 faulthandler_suppress_crash_report();
1082
1083 lock = PyThread_allocate_lock();
1084 if (lock == NULL)
1085 return PyErr_NoMemory();
1086
1087 PyThread_acquire_lock(lock, WAIT_LOCK);
1088
1089 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1090 if (thread == -1) {
1091 PyThread_free_lock(lock);
1092 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1093 return NULL;
1094 }
1095
1096 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001097 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001098 PyThread_acquire_lock(lock, WAIT_LOCK);
1099 PyThread_release_lock(lock);
1100 PyThread_free_lock(lock);
1101
1102 Py_RETURN_NONE;
1103}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001104
Victor Stinner024e37a2011-03-31 01:31:06 +02001105static PyObject *
1106faulthandler_sigfpe(PyObject *self, PyObject *args)
1107{
1108 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1109 PowerPC. Use volatile to disable compile-time optimizations. */
1110 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001111 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001112 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001113 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1114 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001115 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001116 /* This line is never reached, but we pretend to make something with z
1117 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001118 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001119}
1120
Victor Stinnerd727e232011-04-01 12:13:55 +02001121static PyObject *
1122faulthandler_sigabrt(PyObject *self, PyObject *args)
1123{
Victor Stinner7a399122014-09-30 13:40:12 +02001124 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001125 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001126 Py_RETURN_NONE;
1127}
1128
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001129#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001130#define FAULTHANDLER_STACK_OVERFLOW
1131
Victor Stinner8b787962019-12-04 21:10:06 +01001132static uintptr_t
Benjamin Petersonca470632016-09-06 13:47:26 -07001133stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001134{
Victor Stinner8b787962019-12-04 21:10:06 +01001135 /* Allocate (at least) 4096 bytes on the stack at each call.
1136
1137 bpo-23654, bpo-38965: use volatile keyword to prevent tail call
1138 optimization. */
1139 volatile unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001140 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001141 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001142 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001143 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001144 buffer[0] = 1;
1145 buffer[4095] = 0;
1146 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001147}
1148
1149static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301150faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001151{
1152 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001153 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001154 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001155
Victor Stinner7a399122014-09-30 13:40:12 +02001156 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001157 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001158
1159 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1160 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1161 }
1162 else {
1163 lower_limit = 0;
1164 }
1165
1166 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1167 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1168 }
1169 else {
1170 upper_limit = UINTPTR_MAX;
1171 }
1172
1173 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001174 if (sp < stop)
1175 size = stop - sp;
1176 else
1177 size = sp - stop;
1178 PyErr_Format(PyExc_RuntimeError,
1179 "unable to raise a stack overflow (allocated %zu bytes "
1180 "on the stack, %zu recursive calls)",
1181 size, depth);
1182 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001183}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001184#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001185
1186
1187static int
1188faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1189{
Victor Stinner024e37a2011-03-31 01:31:06 +02001190 Py_VISIT(thread.file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001191#ifdef FAULTHANDLER_USER
1192 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001193 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001194 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001195 }
1196#endif
1197 Py_VISIT(fatal_error.file);
1198 return 0;
1199}
1200
Victor Stinner404cdc52016-03-23 10:39:17 +01001201#ifdef MS_WINDOWS
1202static PyObject *
1203faulthandler_raise_exception(PyObject *self, PyObject *args)
1204{
1205 unsigned int code, flags = 0;
1206 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1207 return NULL;
1208 faulthandler_suppress_crash_report();
1209 RaiseException(code, flags, 0, NULL);
1210 Py_RETURN_NONE;
1211}
1212#endif
1213
Victor Stinner024e37a2011-03-31 01:31:06 +02001214PyDoc_STRVAR(module_doc,
1215"faulthandler module.");
1216
1217static PyMethodDef module_methods[] = {
1218 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001219 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001220 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001221 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301222 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001223 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301224 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001225 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1226 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001227 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001228 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001229 "dump the traceback of the current thread, or of all threads "
1230 "if all_threads is True, into file")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001231 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001232 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001233 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001234 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001235 "or each timeout seconds if repeat is True. If exit is True, "
1236 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001237 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301238 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001239 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1240 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001241#ifdef FAULTHANDLER_USER
1242 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001243 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001244 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001245 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001246 "traceback of the current thread, or of all threads if "
1247 "all_threads is True, into file")},
1248 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001249 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001250 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1251 "'signum' registered by register()")},
1252#endif
Victor Stinner50838282014-09-30 13:54:14 +02001253 {"_read_null", faulthandler_read_null, METH_NOARGS,
1254 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001255 "a SIGSEGV or SIGBUS signal depending on the platform")},
1256 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001257 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001258 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1259 PyDoc_STR("fatal_error_c_thread(): "
1260 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001261 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001262 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001263 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1264 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001265#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301266 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001267 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1268#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001269#ifdef MS_WINDOWS
1270 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1271 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1272#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001273 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001274};
1275
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001276static int
1277PyExec_faulthandler(PyObject *module) {
1278 /* Add constants for unit tests */
1279#ifdef MS_WINDOWS
1280 /* RaiseException() codes (prefixed by an underscore) */
1281 if (PyModule_AddIntConstant(module, "_EXCEPTION_ACCESS_VIOLATION",
1282 EXCEPTION_ACCESS_VIOLATION)) {
1283 return -1;
1284 }
1285 if (PyModule_AddIntConstant(module, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1286 EXCEPTION_INT_DIVIDE_BY_ZERO)) {
1287 return -1;
1288 }
1289 if (PyModule_AddIntConstant(module, "_EXCEPTION_STACK_OVERFLOW",
1290 EXCEPTION_STACK_OVERFLOW)) {
1291 return -1;
1292 }
1293
1294 /* RaiseException() flags (prefixed by an underscore) */
1295 if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE",
1296 EXCEPTION_NONCONTINUABLE)) {
1297 return -1;
1298 }
1299 if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1300 EXCEPTION_NONCONTINUABLE_EXCEPTION)) {
1301 return -1;
1302 }
1303#endif
1304 return 0;
1305}
1306
1307static PyModuleDef_Slot faulthandler_slots[] = {
1308 {Py_mod_exec, PyExec_faulthandler},
1309 {0, NULL}
1310};
1311
Victor Stinner024e37a2011-03-31 01:31:06 +02001312static struct PyModuleDef module_def = {
1313 PyModuleDef_HEAD_INIT,
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001314 .m_name = "faulthandler",
1315 .m_doc = module_doc,
1316 .m_methods = module_methods,
1317 .m_traverse = faulthandler_traverse,
1318 .m_slots = faulthandler_slots
Victor Stinner024e37a2011-03-31 01:31:06 +02001319};
1320
1321PyMODINIT_FUNC
1322PyInit_faulthandler(void)
1323{
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001324 return PyModuleDef_Init(&module_def);
Victor Stinner024e37a2011-03-31 01:31:06 +02001325}
1326
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001327static int
1328faulthandler_init_enable(void)
1329{
1330 PyObject *module = PyImport_ImportModule("faulthandler");
1331 if (module == NULL) {
1332 return -1;
1333 }
1334
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001335 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001336 Py_DECREF(module);
1337 if (res == NULL) {
1338 return -1;
1339 }
1340 Py_DECREF(res);
1341
1342 return 0;
1343}
1344
Victor Stinner331a6a52019-05-27 16:39:22 +02001345PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001346_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001347{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001348#ifdef FAULTHANDLER_USE_ALT_STACK
1349 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001350 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001351 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1352 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1353 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1354 platforms. */
1355 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001356#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001357
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001358 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001359
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001360 if (enable) {
1361 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001362 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001363 }
1364 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001365 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001366}
1367
1368void _PyFaulthandler_Fini(void)
1369{
Victor Stinner024e37a2011-03-31 01:31:06 +02001370 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001371 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001372 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001373 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001374 PyThread_free_lock(thread.cancel_event);
1375 thread.cancel_event = NULL;
1376 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001377 if (thread.running) {
1378 PyThread_free_lock(thread.running);
1379 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001380 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001381
1382#ifdef FAULTHANDLER_USER
1383 /* user */
1384 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001385 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001386 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001387 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001388 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001389 user_signals = NULL;
1390 }
1391#endif
1392
1393 /* fatal */
1394 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001395
1396#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001397 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001398 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001399 stack_t current_stack;
1400 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001401 if (sigaltstack(NULL, &current_stack) == 0) {
1402 if (current_stack.ss_sp == stack.ss_sp) {
1403 /* The current alt stack is the one that we installed.
1404 It is safe to restore the old stack that we found when
1405 we installed ours */
1406 sigaltstack(&old_stack, NULL);
1407 } else {
1408 /* Someone switched to a different alt stack and didn't
1409 restore ours when they were done (if they're done).
1410 There's not much we can do in this unlikely case */
1411 }
1412 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001413 PyMem_Free(stack.ss_sp);
1414 stack.ss_sp = NULL;
1415 }
1416#endif
1417}