blob: e03f6d96c8edb941596015231dff953f311a825e [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 Stinner7b5b4292022-03-04 01:12:06 +010032
33// clang uses __attribute__((no_sanitize("undefined")))
34// GCC 4.9+ uses __attribute__((no_sanitize_undefined))
35#if defined(__has_feature) // Clang
36# if __has_feature(undefined_behavior_sanitizer)
37# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
38# endif
39#endif
40#if defined(__GNUC__) \
41 && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
42# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
43#endif
44#ifndef _Py_NO_SANITIZE_UNDEFINED
45# define _Py_NO_SANITIZE_UNDEFINED
46#endif
47
48
Victor Stinnerbd303c12013-11-07 23:07:29 +010049_Py_IDENTIFIER(enable);
50_Py_IDENTIFIER(fileno);
51_Py_IDENTIFIER(flush);
52_Py_IDENTIFIER(stderr);
53
Victor Stinner024e37a2011-03-31 01:31:06 +020054#ifdef HAVE_SIGACTION
55typedef struct sigaction _Py_sighandler_t;
56#else
57typedef PyOS_sighandler_t _Py_sighandler_t;
58#endif
59
60typedef struct {
61 int signum;
62 int enabled;
63 const char* name;
64 _Py_sighandler_t previous;
65 int all_threads;
66} fault_handler_t;
67
68static struct {
69 int enabled;
70 PyObject *file;
71 int fd;
72 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020073 PyInterpreterState *interp;
Victor Stinner46c2b812017-04-21 18:06:13 +020074#ifdef MS_WINDOWS
75 void *exc_handler;
76#endif
Victor Stinner024e37a2011-03-31 01:31:06 +020077} fatal_error = {0, NULL, -1, 0};
78
Victor Stinner024e37a2011-03-31 01:31:06 +020079static struct {
80 PyObject *file;
81 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020082 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020083 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020084 PyInterpreterState *interp;
85 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020086 char *header;
87 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020088 /* The main thread always holds this lock. It is only released when
89 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020090 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020091 PyThread_type_lock cancel_event;
92 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020093 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020094} thread;
Victor Stinner024e37a2011-03-31 01:31:06 +020095
96#ifdef FAULTHANDLER_USER
97typedef struct {
98 int enabled;
99 PyObject *file;
100 int fd;
101 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200102 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +0200103 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200104 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200105} user_signal_t;
106
107static user_signal_t *user_signals;
108
109/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +0200110#ifndef NSIG
111# if defined(_NSIG)
112# define NSIG _NSIG /* For BSD/SysV */
113# elif defined(_SIGMAX)
114# define NSIG (_SIGMAX + 1) /* For QNX */
115# elif defined(SIGMAX)
116# define NSIG (SIGMAX + 1) /* For djgpp */
117# else
118# define NSIG 64 /* Use a reasonable default value */
119# endif
120#endif
121
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200122static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200123#endif /* FAULTHANDLER_USER */
124
125
126static fault_handler_t faulthandler_handlers[] = {
127#ifdef SIGBUS
128 {SIGBUS, 0, "Bus error", },
129#endif
130#ifdef SIGILL
131 {SIGILL, 0, "Illegal instruction", },
132#endif
133 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200134 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200135 /* define SIGSEGV at the end to make it the default choice if searching the
136 handler fails in faulthandler_fatal_error() */
137 {SIGSEGV, 0, "Segmentation fault", }
138};
Victor Stinner404cdc52016-03-23 10:39:17 +0100139static const size_t faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200140 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200141
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100142/* Using an alternative stack requires sigaltstack()
143 and sigaction() SA_ONSTACK */
144#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
145# define FAULTHANDLER_USE_ALT_STACK
146#endif
147
148#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +0200149static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700150static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200151#endif
152
153
154/* Get the file descriptor of a file by calling its fileno() method and then
155 call its flush() method.
156
157 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100158 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200159
Victor Stinner95bb7142015-03-12 15:32:03 +0100160 On success, return the file descriptor and write the new file into *file_ptr.
161 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200162
Victor Stinner95bb7142015-03-12 15:32:03 +0100163static int
164faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200165{
166 PyObject *result;
167 long fd_long;
168 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100169 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200170
171 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100172 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200173 if (file == NULL) {
174 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100175 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200176 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200177 if (file == Py_None) {
178 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100179 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200180 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200181 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100182 else if (PyLong_Check(file)) {
183 fd = _PyLong_AsInt(file);
184 if (fd == -1 && PyErr_Occurred())
185 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700186 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100187 PyErr_SetString(PyExc_ValueError,
188 "file is not a valid file descripter");
189 return -1;
190 }
191 *file_ptr = NULL;
192 return fd;
193 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200194
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200195 result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno);
Victor Stinner024e37a2011-03-31 01:31:06 +0200196 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100197 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200198
199 fd = -1;
200 if (PyLong_Check(result)) {
201 fd_long = PyLong_AsLong(result);
202 if (0 <= fd_long && fd_long < INT_MAX)
203 fd = (int)fd_long;
204 }
205 Py_DECREF(result);
206
207 if (fd == -1) {
208 PyErr_SetString(PyExc_RuntimeError,
209 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100210 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200211 }
212
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200213 result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200214 if (result != NULL)
215 Py_DECREF(result);
216 else {
217 /* ignore flush() error */
218 PyErr_Clear();
219 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100220 *file_ptr = file;
221 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200222}
223
Victor Stinnera4de6d82011-04-09 00:47:23 +0200224/* Get the state of the current thread: only call this function if the current
225 thread holds the GIL. Raise an exception on error. */
226static PyThreadState*
227get_thread_state(void)
228{
Victor Stinner5592f2b2021-02-19 13:21:28 +0100229 PyThreadState *tstate = _PyThreadState_GET();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200230 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100231 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200232 PyErr_SetString(PyExc_RuntimeError,
233 "unable to get the current thread state");
234 return NULL;
235 }
236 return tstate;
237}
238
Victor Stinnerc7489a52015-04-01 18:48:58 +0200239static void
240faulthandler_dump_traceback(int fd, int all_threads,
241 PyInterpreterState *interp)
242{
243 static volatile int reentrant = 0;
244 PyThreadState *tstate;
245
246 if (reentrant)
247 return;
248
249 reentrant = 1;
250
Victor Stinnerc7489a52015-04-01 18:48:58 +0200251 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
252 are thus delivered to the thread that caused the fault. Get the Python
253 thread state of the current thread.
254
255 PyThreadState_Get() doesn't give the state of the thread that caused the
256 fault if the thread released the GIL, and so this function cannot be
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900257 used. Read the thread specific storage (TSS) instead: call
Victor Stinnerc7489a52015-04-01 18:48:58 +0200258 PyGILState_GetThisThreadState(). */
259 tstate = PyGILState_GetThisThreadState();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200260
Victor Stinner861d9ab2016-03-16 22:45:24 +0100261 if (all_threads) {
262 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
263 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200264 else {
265 if (tstate != NULL)
266 _Py_DumpTraceback(fd, tstate);
267 }
268
269 reentrant = 0;
270}
271
Victor Stinner024e37a2011-03-31 01:31:06 +0200272static PyObject*
273faulthandler_dump_traceback_py(PyObject *self,
274 PyObject *args, PyObject *kwargs)
275{
276 static char *kwlist[] = {"file", "all_threads", NULL};
277 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200278 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200279 PyThreadState *tstate;
280 const char *errmsg;
281 int fd;
282
283 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
284 "|Oi:dump_traceback", kwlist,
285 &file, &all_threads))
286 return NULL;
287
Victor Stinner95bb7142015-03-12 15:32:03 +0100288 fd = faulthandler_get_fileno(&file);
289 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200290 return NULL;
291
Victor Stinnera4de6d82011-04-09 00:47:23 +0200292 tstate = get_thread_state();
293 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200294 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200295
296 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100297 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200298 if (errmsg != NULL) {
299 PyErr_SetString(PyExc_RuntimeError, errmsg);
300 return NULL;
301 }
302 }
303 else {
304 _Py_DumpTraceback(fd, tstate);
305 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200306
307 if (PyErr_CheckSignals())
308 return NULL;
309
Victor Stinner024e37a2011-03-31 01:31:06 +0200310 Py_RETURN_NONE;
311}
312
Victor Stinner404cdc52016-03-23 10:39:17 +0100313static void
314faulthandler_disable_fatal_handler(fault_handler_t *handler)
315{
316 if (!handler->enabled)
317 return;
318 handler->enabled = 0;
319#ifdef HAVE_SIGACTION
320 (void)sigaction(handler->signum, &handler->previous, NULL);
321#else
322 (void)signal(handler->signum, handler->previous);
323#endif
324}
325
Victor Stinner024e37a2011-03-31 01:31:06 +0200326
Victor Stinner410dd7d2011-05-11 20:56:08 +0200327/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200328
329 Display the current Python traceback, restore the previous handler and call
330 the previous handler.
331
Victor Stinner410dd7d2011-05-11 20:56:08 +0200332 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200333 signal handler would not be called (for an unknown reason). The execution of
334 the program continues at faulthandler_fatal_error() exit, but the same
335 instruction will raise the same fault (signal), and so the previous handler
336 will be called.
337
Victor Stinner410dd7d2011-05-11 20:56:08 +0200338 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200339
340static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200341faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200342{
343 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100344 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200345 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200346 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200347
348 if (!fatal_error.enabled)
349 return;
350
351 for (i=0; i < faulthandler_nsignals; i++) {
352 handler = &faulthandler_handlers[i];
353 if (handler->signum == signum)
354 break;
355 }
356 if (handler == NULL) {
357 /* faulthandler_nsignals == 0 (unlikely) */
358 return;
359 }
360
361 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100362 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200363
364 PUTS(fd, "Fatal Python error: ");
365 PUTS(fd, handler->name);
366 PUTS(fd, "\n\n");
367
Victor Stinnerc7489a52015-04-01 18:48:58 +0200368 faulthandler_dump_traceback(fd, fatal_error.all_threads,
369 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200370
Victor Stinner250035d2021-01-18 20:47:13 +0100371 _Py_DumpExtensionModules(fd, fatal_error.interp);
372
Victor Stinnerc9256172011-05-07 12:20:11 +0200373 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200374#ifdef MS_WINDOWS
375 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200376 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200377 handler, because the Windows signal handler would not be called */
378 return;
379 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200380#endif
R David Murrayfc069992013-12-13 20:52:19 -0500381 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200382 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
383 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200384}
385
Victor Stinner404cdc52016-03-23 10:39:17 +0100386#ifdef MS_WINDOWS
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700387static int
388faulthandler_ignore_exception(DWORD code)
389{
390 /* bpo-30557: ignore exceptions which are not errors */
391 if (!(code & 0x80000000)) {
392 return 1;
393 }
394 /* bpo-31701: ignore MSC and COM exceptions
395 E0000000 + code */
396 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
397 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
398 return 1;
399 }
400 /* Interesting exception: log it with the Python traceback */
401 return 0;
402}
403
Victor Stinner404cdc52016-03-23 10:39:17 +0100404static LONG WINAPI
405faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
406{
407 const int fd = fatal_error.fd;
408 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100409 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100410
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700411 if (faulthandler_ignore_exception(code)) {
412 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100413 return EXCEPTION_CONTINUE_SEARCH;
414 }
415
416 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100417 switch (code)
418 {
419 /* only format most common errors */
420 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
421 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
422 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
423 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
424 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
425 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
426 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
427 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700428 PUTS(fd, "code 0x");
429 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100430 }
431 PUTS(fd, "\n\n");
432
433 if (code == EXCEPTION_ACCESS_VIOLATION) {
434 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200435 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100436 fault_handler_t *handler = &faulthandler_handlers[i];
437 if (handler->signum == SIGSEGV) {
438 faulthandler_disable_fatal_handler(handler);
439 break;
440 }
441 }
442 }
443
444 faulthandler_dump_traceback(fd, fatal_error.all_threads,
445 fatal_error.interp);
446
447 /* call the next exception handler */
448 return EXCEPTION_CONTINUE_SEARCH;
449}
450#endif
451
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100452
453#ifdef FAULTHANDLER_USE_ALT_STACK
454static int
455faulthandler_allocate_stack(void)
456{
457 if (stack.ss_sp != NULL) {
458 return 0;
459 }
460 /* Allocate an alternate stack for faulthandler() signal handler
461 to be able to execute a signal handler on a stack overflow error */
462 stack.ss_sp = PyMem_Malloc(stack.ss_size);
463 if (stack.ss_sp == NULL) {
464 PyErr_NoMemory();
465 return -1;
466 }
467
468 int err = sigaltstack(&stack, &old_stack);
469 if (err) {
470 /* Release the stack to retry sigaltstack() next time */
471 PyMem_Free(stack.ss_sp);
472 stack.ss_sp = NULL;
473
474 PyErr_SetFromErrno(PyExc_OSError);
475 return -1;
476 }
477 return 0;
478}
479#endif
480
481
Victor Stinnerd727e232011-04-01 12:13:55 +0200482/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200483
doko@ubuntu.combc731502016-05-18 01:06:01 +0200484static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100485faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200486{
Victor Stinner404cdc52016-03-23 10:39:17 +0100487 if (fatal_error.enabled) {
488 return 0;
489 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100490 fatal_error.enabled = 1;
491
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100492#ifdef FAULTHANDLER_USE_ALT_STACK
493 if (faulthandler_allocate_stack() < 0) {
494 return -1;
495 }
496#endif
497
Victor Stinner46c2b812017-04-21 18:06:13 +0200498 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100499 fault_handler_t *handler;
Victor Stinner928ad282016-03-23 15:19:12 +0100500 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100501
Victor Stinner928ad282016-03-23 15:19:12 +0100502 handler = &faulthandler_handlers[i];
503 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100504#ifdef HAVE_SIGACTION
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100505 struct sigaction action;
Victor Stinner404cdc52016-03-23 10:39:17 +0100506 action.sa_handler = faulthandler_fatal_error;
507 sigemptyset(&action.sa_mask);
508 /* Do not prevent the signal from being received from within
509 its own signal handler */
510 action.sa_flags = SA_NODEFER;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100511#ifdef FAULTHANDLER_USE_ALT_STACK
512 assert(stack.ss_sp != NULL);
513 /* Call the signal handler on an alternate signal stack
514 provided by sigaltstack() */
515 action.sa_flags |= SA_ONSTACK;
Victor Stinner404cdc52016-03-23 10:39:17 +0100516#endif
517 err = sigaction(handler->signum, &action, &handler->previous);
518#else
519 handler->previous = signal(handler->signum,
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100520 faulthandler_fatal_error);
Victor Stinner404cdc52016-03-23 10:39:17 +0100521 err = (handler->previous == SIG_ERR);
522#endif
523 if (err) {
524 PyErr_SetFromErrno(PyExc_RuntimeError);
525 return -1;
526 }
527
528 handler->enabled = 1;
529 }
530
531#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200532 assert(fatal_error.exc_handler == NULL);
533 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100534#endif
535 return 0;
536}
537
538static PyObject*
539faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
540{
541 static char *kwlist[] = {"file", "all_threads", NULL};
542 PyObject *file = NULL;
543 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200544 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200545 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200546
547 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
548 "|Oi:enable", kwlist, &file, &all_threads))
549 return NULL;
550
Victor Stinner95bb7142015-03-12 15:32:03 +0100551 fd = faulthandler_get_fileno(&file);
552 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200553 return NULL;
554
Victor Stinnera4de6d82011-04-09 00:47:23 +0200555 tstate = get_thread_state();
556 if (tstate == NULL)
557 return NULL;
558
Victor Stinner95bb7142015-03-12 15:32:03 +0100559 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300560 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200561 fatal_error.fd = fd;
562 fatal_error.all_threads = all_threads;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100563 fatal_error.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200564
Victor Stinner404cdc52016-03-23 10:39:17 +0100565 if (faulthandler_enable() < 0) {
566 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200567 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100568
Victor Stinner024e37a2011-03-31 01:31:06 +0200569 Py_RETURN_NONE;
570}
571
572static void
573faulthandler_disable(void)
574{
Victor Stinner024e37a2011-03-31 01:31:06 +0200575 if (fatal_error.enabled) {
576 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200577 for (size_t i=0; i < faulthandler_nsignals; i++) {
578 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200579 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100580 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200581 }
582 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200583#ifdef MS_WINDOWS
584 if (fatal_error.exc_handler != NULL) {
585 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
586 fatal_error.exc_handler = NULL;
587 }
588#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200589 Py_CLEAR(fatal_error.file);
590}
591
592static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530593faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200594{
595 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200596 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200597 }
598 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200599 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200600}
601
602static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530603faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200604{
605 return PyBool_FromLong(fatal_error.enabled);
606}
607
Victor Stinner024e37a2011-03-31 01:31:06 +0200608static void
609faulthandler_thread(void *unused)
610{
611 PyLockStatus st;
612 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200613 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200614#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200615 sigset_t set;
616
617 /* we don't want to receive any signal */
618 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200619 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200620#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200621
622 do {
623 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200624 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200625 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200626 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200627 break;
628 }
629 /* Timeout => dump traceback */
630 assert(st == PY_LOCK_FAILURE);
631
Victor Stinnerc7489a52015-04-01 18:48:58 +0200632 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200633
Victor Stinner861d9ab2016-03-16 22:45:24 +0100634 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200635 ok = (errmsg == NULL);
636
637 if (thread.exit)
638 _exit(1);
639 } while (ok && thread.repeat);
640
641 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200642 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200643}
644
645static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200646cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200647{
Thomas A Caswelle2783352019-08-29 12:30:04 -0400648 /* If not scheduled, nothing to cancel */
649 if (!thread.cancel_event) {
650 return;
651 }
652
Victor Stinner410dd7d2011-05-11 20:56:08 +0200653 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200654 PyThread_release_lock(thread.cancel_event);
655
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200656 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200657 PyThread_acquire_lock(thread.running, 1);
658 PyThread_release_lock(thread.running);
659
660 /* The main thread should always hold the cancel_event lock */
661 PyThread_acquire_lock(thread.cancel_event, 1);
662
Victor Stinner024e37a2011-03-31 01:31:06 +0200663 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200664 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200665 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200666 thread.header = NULL;
667 }
668}
669
Victor Stinner93fd4782017-10-27 07:27:12 -0700670#define SEC_TO_US (1000 * 1000)
671
Victor Stinnerc790a532011-04-08 13:39:59 +0200672static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700673format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200674{
Victor Stinner93fd4782017-10-27 07:27:12 -0700675 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200676 char buffer[100];
677
Victor Stinner93fd4782017-10-27 07:27:12 -0700678 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
679 sec = (unsigned long)(us / SEC_TO_US);
680 us %= SEC_TO_US;
681
Victor Stinnerc790a532011-04-08 13:39:59 +0200682 min = sec / 60;
683 sec %= 60;
684 hour = min / 60;
685 min %= 60;
686
Victor Stinner93fd4782017-10-27 07:27:12 -0700687 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200688 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700689 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
690 hour, min, sec, (unsigned int)us);
691 }
692 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200693 PyOS_snprintf(buffer, sizeof(buffer),
694 "Timeout (%lu:%02lu:%02lu)!\n",
695 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700696 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200697 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200698}
699
700static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200701faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200702 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200703{
704 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700705 PyObject *timeout_obj;
706 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200707 int repeat = 0;
708 PyObject *file = NULL;
709 int fd;
710 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200711 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200712 char *header;
713 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200714
715 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700716 "O|iOi:dump_traceback_later", kwlist,
717 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200718 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700719
720 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
721 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200722 return NULL;
723 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700724 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200725 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200726 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
727 return NULL;
728 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700729 /* Limit to LONG_MAX seconds for format_timeout() */
730 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
731 PyErr_SetString(PyExc_OverflowError,
732 "timeout value is too large");
733 return NULL;
734 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200735
Victor Stinnera4de6d82011-04-09 00:47:23 +0200736 tstate = get_thread_state();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100737 if (tstate == NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200738 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100739 }
Victor Stinner96994402011-04-07 11:37:19 +0200740
Victor Stinner95bb7142015-03-12 15:32:03 +0100741 fd = faulthandler_get_fileno(&file);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100742 if (fd < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200743 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100744 }
745
746 if (!thread.running) {
747 thread.running = PyThread_allocate_lock();
748 if (!thread.running) {
749 return PyErr_NoMemory();
750 }
751 }
752 if (!thread.cancel_event) {
753 thread.cancel_event = PyThread_allocate_lock();
754 if (!thread.cancel_event || !thread.running) {
755 return PyErr_NoMemory();
756 }
757
758 /* cancel_event starts to be acquired: it's only released to cancel
759 the thread. */
760 PyThread_acquire_lock(thread.cancel_event, 1);
761 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200762
Victor Stinnerc790a532011-04-08 13:39:59 +0200763 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700764 header = format_timeout(timeout_us);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100765 if (header == NULL) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200766 return PyErr_NoMemory();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100767 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200768 header_len = strlen(header);
769
Victor Stinner024e37a2011-03-31 01:31:06 +0200770 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200771 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200772
Victor Stinner95bb7142015-03-12 15:32:03 +0100773 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300774 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200775 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700776 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
777 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200778 thread.repeat = repeat;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100779 thread.interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200780 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200781 thread.header = header;
782 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200783
784 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200785 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200786
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200787 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200788 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200789 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200790 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200791 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200792 PyErr_SetString(PyExc_RuntimeError,
793 "unable to start watchdog thread");
794 return NULL;
795 }
796
797 Py_RETURN_NONE;
798}
799
800static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530801faulthandler_cancel_dump_traceback_later_py(PyObject *self,
802 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200803{
Georg Brandldeb92b52012-09-22 08:58:55 +0200804 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200805 Py_RETURN_NONE;
806}
Victor Stinner024e37a2011-03-31 01:31:06 +0200807
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100808
Victor Stinner024e37a2011-03-31 01:31:06 +0200809#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200810static int
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100811faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200812{
813#ifdef HAVE_SIGACTION
814 struct sigaction action;
815 action.sa_handler = faulthandler_user;
816 sigemptyset(&action.sa_mask);
817 /* if the signal is received while the kernel is executing a system
818 call, try to restart the system call instead of interrupting it and
819 return EINTR. */
820 action.sa_flags = SA_RESTART;
821 if (chain) {
822 /* do not prevent the signal from being received from within its
823 own signal handler */
824 action.sa_flags = SA_NODEFER;
825 }
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100826#ifdef FAULTHANDLER_USE_ALT_STACK
827 assert(stack.ss_sp != NULL);
828 /* Call the signal handler on an alternate signal stack
829 provided by sigaltstack() */
830 action.sa_flags |= SA_ONSTACK;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200831#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100832 return sigaction(signum, &action, previous_p);
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200833#else
834 _Py_sighandler_t previous;
835 previous = signal(signum, faulthandler_user);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100836 if (previous_p != NULL) {
837 *previous_p = previous;
838 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200839 return (previous == SIG_ERR);
840#endif
841}
842
Victor Stinner024e37a2011-03-31 01:31:06 +0200843/* Handler of user signals (e.g. SIGUSR1).
844
845 Dump the traceback of the current thread, or of all threads if
846 thread.all_threads is true.
847
848 This function is signal safe and should only call signal safe functions. */
849
850static void
851faulthandler_user(int signum)
852{
853 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200854 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200855
856 user = &user_signals[signum];
857 if (!user->enabled)
858 return;
859
Victor Stinnerc7489a52015-04-01 18:48:58 +0200860 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200861
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200862#ifdef HAVE_SIGACTION
863 if (user->chain) {
864 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200865 errno = save_errno;
866
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200867 /* call the previous signal handler */
868 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200869
870 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200871 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200872 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200873 }
874#else
875 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200876 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200877 /* call the previous signal handler */
878 user->previous(signum);
879 }
880#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200881}
882
883static int
884check_signum(int signum)
885{
Victor Stinner46c2b812017-04-21 18:06:13 +0200886 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200887 if (faulthandler_handlers[i].signum == signum) {
888 PyErr_Format(PyExc_RuntimeError,
889 "signal %i cannot be registered, "
890 "use enable() instead",
891 signum);
892 return 0;
893 }
894 }
895 if (signum < 1 || NSIG <= signum) {
896 PyErr_SetString(PyExc_ValueError, "signal number out of range");
897 return 0;
898 }
899 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200900}
901
902static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200903faulthandler_register_py(PyObject *self,
904 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200905{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200906 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200907 int signum;
908 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200909 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200910 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200911 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200912 user_signal_t *user;
913 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200914 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200915 int err;
916
917 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200918 "i|Oii:register", kwlist,
919 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200920 return NULL;
921
Victor Stinner44378d42011-04-01 15:37:12 +0200922 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200923 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200924
Victor Stinnera4de6d82011-04-09 00:47:23 +0200925 tstate = get_thread_state();
926 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200927 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200928
Victor Stinner95bb7142015-03-12 15:32:03 +0100929 fd = faulthandler_get_fileno(&file);
930 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200931 return NULL;
932
933 if (user_signals == NULL) {
Andy Lester7668a8b2020-03-24 23:26:44 -0500934 user_signals = PyMem_Calloc(NSIG, sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200935 if (user_signals == NULL)
936 return PyErr_NoMemory();
937 }
938 user = &user_signals[signum];
939
940 if (!user->enabled) {
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100941#ifdef FAULTHANDLER_USE_ALT_STACK
942 if (faulthandler_allocate_stack() < 0) {
943 return NULL;
944 }
945#endif
946
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200947 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200948 if (err) {
949 PyErr_SetFromErrno(PyExc_OSError);
950 return NULL;
951 }
Victor Stinner8d379542013-07-02 00:14:56 +0200952
953 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200954 }
955
Victor Stinner95bb7142015-03-12 15:32:03 +0100956 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300957 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200958 user->fd = fd;
959 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200960 user->chain = chain;
Victor Stinner8fb02b62020-03-13 23:38:08 +0100961 user->interp = PyThreadState_GetInterpreter(tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200962 user->enabled = 1;
963
964 Py_RETURN_NONE;
965}
966
967static int
968faulthandler_unregister(user_signal_t *user, int signum)
969{
Victor Stinnera01ca122011-04-01 12:56:17 +0200970 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200971 return 0;
972 user->enabled = 0;
973#ifdef HAVE_SIGACTION
974 (void)sigaction(signum, &user->previous, NULL);
975#else
976 (void)signal(signum, user->previous);
977#endif
978 Py_CLEAR(user->file);
979 user->fd = -1;
980 return 1;
981}
982
983static PyObject*
984faulthandler_unregister_py(PyObject *self, PyObject *args)
985{
986 int signum;
987 user_signal_t *user;
988 int change;
989
990 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
991 return NULL;
992
Victor Stinner44378d42011-04-01 15:37:12 +0200993 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200994 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200995
Victor Stinnercfa71232011-04-08 12:48:15 +0200996 if (user_signals == NULL)
997 Py_RETURN_FALSE;
998
Victor Stinner024e37a2011-03-31 01:31:06 +0200999 user = &user_signals[signum];
1000 change = faulthandler_unregister(user, signum);
1001 return PyBool_FromLong(change);
1002}
1003#endif /* FAULTHANDLER_USER */
1004
1005
Victor Stinner7a399122014-09-30 13:40:12 +02001006static void
1007faulthandler_suppress_crash_report(void)
1008{
1009#ifdef MS_WINDOWS
1010 UINT mode;
1011
1012 /* Configure Windows to not display the Windows Error Reporting dialog */
1013 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
1014 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
1015#endif
1016
1017#ifdef HAVE_SYS_RESOURCE_H
1018 struct rlimit rl;
1019
1020 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +01001021 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +02001022 rl.rlim_cur = 0;
1023 setrlimit(RLIMIT_CORE, &rl);
1024 }
1025#endif
1026
1027#ifdef _MSC_VER
1028 /* Visual Studio: configure abort() to not display an error message nor
1029 open a popup asking to report the fault. */
1030 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1031#endif
1032}
1033
Victor Stinner7b5b4292022-03-04 01:12:06 +01001034static PyObject* _Py_NO_SANITIZE_UNDEFINED
Victor Stinner024e37a2011-03-31 01:31:06 +02001035faulthandler_read_null(PyObject *self, PyObject *args)
1036{
Victor Stinnera2477202012-01-30 00:07:43 +01001037 volatile int *x;
1038 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +01001039
Victor Stinner7a399122014-09-30 13:40:12 +02001040 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +01001041 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +02001042 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +02001043 return PyLong_FromLong(y);
1044
1045}
1046
Victor Stinner50838282014-09-30 13:54:14 +02001047static void
1048faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +02001049{
Victor Stinner7a399122014-09-30 13:40:12 +02001050 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001051#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +02001052 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
1053 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +02001054 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +02001055 SIGSEGV was raised by the kernel because of a fault, and so if the
1056 program retries to execute the same instruction, the fault will be
1057 raised again.
1058
1059 Here the fault is simulated by a fake SIGSEGV signal raised by the
1060 application. We have to raise SIGSEGV at lease twice: once for
1061 faulthandler_fatal_error(), and one more time for the previous signal
1062 handler. */
1063 while(1)
1064 raise(SIGSEGV);
1065#else
1066 raise(SIGSEGV);
1067#endif
Victor Stinner50838282014-09-30 13:54:14 +02001068}
1069
1070static PyObject *
1071faulthandler_sigsegv(PyObject *self, PyObject *args)
1072{
1073 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +01001074 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +02001075 return NULL;
1076
1077 if (release_gil) {
1078 Py_BEGIN_ALLOW_THREADS
1079 faulthandler_raise_sigsegv();
1080 Py_END_ALLOW_THREADS
1081 } else {
1082 faulthandler_raise_sigsegv();
1083 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001084 Py_RETURN_NONE;
1085}
1086
Victor Stinner2a4903f2020-01-30 13:09:11 +01001087static void _Py_NO_RETURN
Victor Stinner861d9ab2016-03-16 22:45:24 +01001088faulthandler_fatal_error_thread(void *plock)
1089{
Victor Stinner861d9ab2016-03-16 22:45:24 +01001090 Py_FatalError("in new thread");
Victor Stinner861d9ab2016-03-16 22:45:24 +01001091}
1092
1093static PyObject *
1094faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1095{
1096 long thread;
1097 PyThread_type_lock lock;
1098
1099 faulthandler_suppress_crash_report();
1100
1101 lock = PyThread_allocate_lock();
1102 if (lock == NULL)
1103 return PyErr_NoMemory();
1104
1105 PyThread_acquire_lock(lock, WAIT_LOCK);
1106
1107 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1108 if (thread == -1) {
1109 PyThread_free_lock(lock);
1110 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1111 return NULL;
1112 }
1113
1114 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001115 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001116 PyThread_acquire_lock(lock, WAIT_LOCK);
1117 PyThread_release_lock(lock);
1118 PyThread_free_lock(lock);
1119
1120 Py_RETURN_NONE;
1121}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001122
Victor Stinner7b5b4292022-03-04 01:12:06 +01001123static PyObject* _Py_NO_SANITIZE_UNDEFINED
Victor Stinner024e37a2011-03-31 01:31:06 +02001124faulthandler_sigfpe(PyObject *self, PyObject *args)
1125{
Victor Stinner7b5b4292022-03-04 01:12:06 +01001126 faulthandler_suppress_crash_report();
1127
Victor Stinner024e37a2011-03-31 01:31:06 +02001128 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1129 PowerPC. Use volatile to disable compile-time optimizations. */
1130 volatile int x = 1, y = 0, z;
1131 z = x / y;
Victor Stinner7b5b4292022-03-04 01:12:06 +01001132
Victor Stinner410dd7d2011-05-11 20:56:08 +02001133 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1134 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001135 raise(SIGFPE);
Victor Stinner7b5b4292022-03-04 01:12:06 +01001136
Victor Stinner410dd7d2011-05-11 20:56:08 +02001137 /* This line is never reached, but we pretend to make something with z
1138 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001139 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001140}
1141
Victor Stinnerd727e232011-04-01 12:13:55 +02001142static PyObject *
1143faulthandler_sigabrt(PyObject *self, PyObject *args)
1144{
Victor Stinner7a399122014-09-30 13:40:12 +02001145 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001146 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001147 Py_RETURN_NONE;
1148}
1149
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001150#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001151#define FAULTHANDLER_STACK_OVERFLOW
1152
Victor Stinner8b787962019-12-04 21:10:06 +01001153static uintptr_t
Benjamin Petersonca470632016-09-06 13:47:26 -07001154stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001155{
Victor Stinner8b787962019-12-04 21:10:06 +01001156 /* Allocate (at least) 4096 bytes on the stack at each call.
1157
1158 bpo-23654, bpo-38965: use volatile keyword to prevent tail call
1159 optimization. */
1160 volatile unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001161 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001162 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001163 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001164 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001165 buffer[0] = 1;
1166 buffer[4095] = 0;
1167 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001168}
1169
1170static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301171faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001172{
1173 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001174 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001175 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001176
Victor Stinner7a399122014-09-30 13:40:12 +02001177 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001178 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001179
1180 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1181 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1182 }
1183 else {
1184 lower_limit = 0;
1185 }
1186
1187 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1188 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1189 }
1190 else {
1191 upper_limit = UINTPTR_MAX;
1192 }
1193
1194 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001195 if (sp < stop)
1196 size = stop - sp;
1197 else
1198 size = sp - stop;
1199 PyErr_Format(PyExc_RuntimeError,
1200 "unable to raise a stack overflow (allocated %zu bytes "
1201 "on the stack, %zu recursive calls)",
1202 size, depth);
1203 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001204}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001205#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001206
1207
1208static int
1209faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1210{
Victor Stinner024e37a2011-03-31 01:31:06 +02001211 Py_VISIT(thread.file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001212#ifdef FAULTHANDLER_USER
1213 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001214 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001215 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001216 }
1217#endif
1218 Py_VISIT(fatal_error.file);
1219 return 0;
1220}
1221
Victor Stinner404cdc52016-03-23 10:39:17 +01001222#ifdef MS_WINDOWS
1223static PyObject *
1224faulthandler_raise_exception(PyObject *self, PyObject *args)
1225{
1226 unsigned int code, flags = 0;
1227 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1228 return NULL;
1229 faulthandler_suppress_crash_report();
1230 RaiseException(code, flags, 0, NULL);
1231 Py_RETURN_NONE;
1232}
1233#endif
1234
Victor Stinner024e37a2011-03-31 01:31:06 +02001235PyDoc_STRVAR(module_doc,
1236"faulthandler module.");
1237
1238static PyMethodDef module_methods[] = {
1239 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001240 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001241 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001242 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301243 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001244 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301245 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001246 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1247 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001248 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001249 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001250 "dump the traceback of the current thread, or of all threads "
1251 "if all_threads is True, into file")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001252 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001253 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001254 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001255 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001256 "or each timeout seconds if repeat is True. If exit is True, "
1257 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001258 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301259 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001260 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1261 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001262#ifdef FAULTHANDLER_USER
1263 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001264 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001265 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001266 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001267 "traceback of the current thread, or of all threads if "
1268 "all_threads is True, into file")},
1269 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001270 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001271 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1272 "'signum' registered by register()")},
1273#endif
Victor Stinner50838282014-09-30 13:54:14 +02001274 {"_read_null", faulthandler_read_null, METH_NOARGS,
1275 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001276 "a SIGSEGV or SIGBUS signal depending on the platform")},
1277 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001278 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001279 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1280 PyDoc_STR("fatal_error_c_thread(): "
1281 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001282 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001283 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001284 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1285 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001286#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301287 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001288 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1289#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001290#ifdef MS_WINDOWS
1291 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1292 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1293#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001294 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001295};
1296
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001297static int
1298PyExec_faulthandler(PyObject *module) {
1299 /* Add constants for unit tests */
1300#ifdef MS_WINDOWS
1301 /* RaiseException() codes (prefixed by an underscore) */
1302 if (PyModule_AddIntConstant(module, "_EXCEPTION_ACCESS_VIOLATION",
1303 EXCEPTION_ACCESS_VIOLATION)) {
1304 return -1;
1305 }
1306 if (PyModule_AddIntConstant(module, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1307 EXCEPTION_INT_DIVIDE_BY_ZERO)) {
1308 return -1;
1309 }
1310 if (PyModule_AddIntConstant(module, "_EXCEPTION_STACK_OVERFLOW",
1311 EXCEPTION_STACK_OVERFLOW)) {
1312 return -1;
1313 }
1314
1315 /* RaiseException() flags (prefixed by an underscore) */
1316 if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE",
1317 EXCEPTION_NONCONTINUABLE)) {
1318 return -1;
1319 }
1320 if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1321 EXCEPTION_NONCONTINUABLE_EXCEPTION)) {
1322 return -1;
1323 }
1324#endif
1325 return 0;
1326}
1327
1328static PyModuleDef_Slot faulthandler_slots[] = {
1329 {Py_mod_exec, PyExec_faulthandler},
1330 {0, NULL}
1331};
1332
Victor Stinner024e37a2011-03-31 01:31:06 +02001333static struct PyModuleDef module_def = {
1334 PyModuleDef_HEAD_INIT,
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001335 .m_name = "faulthandler",
1336 .m_doc = module_doc,
1337 .m_methods = module_methods,
1338 .m_traverse = faulthandler_traverse,
1339 .m_slots = faulthandler_slots
Victor Stinner024e37a2011-03-31 01:31:06 +02001340};
1341
1342PyMODINIT_FUNC
1343PyInit_faulthandler(void)
1344{
Dong-hee Nac0b214b2020-07-04 01:36:47 +09001345 return PyModuleDef_Init(&module_def);
Victor Stinner024e37a2011-03-31 01:31:06 +02001346}
1347
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001348static int
1349faulthandler_init_enable(void)
1350{
1351 PyObject *module = PyImport_ImportModule("faulthandler");
1352 if (module == NULL) {
1353 return -1;
1354 }
1355
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001356 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001357 Py_DECREF(module);
1358 if (res == NULL) {
1359 return -1;
1360 }
1361 Py_DECREF(res);
1362
1363 return 0;
1364}
1365
Victor Stinner331a6a52019-05-27 16:39:22 +02001366PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001367_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001368{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001369#ifdef FAULTHANDLER_USE_ALT_STACK
1370 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001371 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001372 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1373 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1374 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1375 platforms. */
1376 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001377#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001378
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001379 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001380
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001381 if (enable) {
1382 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001383 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001384 }
1385 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001386 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001387}
1388
1389void _PyFaulthandler_Fini(void)
1390{
Victor Stinner024e37a2011-03-31 01:31:06 +02001391 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001392 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001393 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001394 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001395 PyThread_free_lock(thread.cancel_event);
1396 thread.cancel_event = NULL;
1397 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001398 if (thread.running) {
1399 PyThread_free_lock(thread.running);
1400 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001401 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001402
1403#ifdef FAULTHANDLER_USER
1404 /* user */
1405 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001406 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001407 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001408 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001409 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001410 user_signals = NULL;
1411 }
1412#endif
1413
1414 /* fatal */
1415 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001416
1417#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001418 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001419 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001420 stack_t current_stack;
1421 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001422 if (sigaltstack(NULL, &current_stack) == 0) {
1423 if (current_stack.ss_sp == stack.ss_sp) {
1424 /* The current alt stack is the one that we installed.
1425 It is safe to restore the old stack that we found when
1426 we installed ours */
1427 sigaltstack(&old_stack, NULL);
1428 } else {
1429 /* Someone switched to a different alt stack and didn't
1430 restore ours when they were done (if they're done).
1431 There's not much we can do in this unlikely case */
1432 }
1433 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001434 PyMem_Free(stack.ss_sp);
1435 stack.ss_sp = NULL;
1436 }
1437#endif
1438}