blob: 35e7b34c29ccd5d2fecf30afe4966ffe7c1a1de3 [file] [log] [blame]
Victor Stinner024e37a2011-03-31 01:31:06 +02001#include "Python.h"
Victor Stinner331a6a52019-05-27 16:39:22 +02002#include "pycore_initconfig.h"
Victor Stinnered488662019-05-20 00:14:57 +02003#include "pycore_traceback.h"
Victor Stinner024e37a2011-03-31 01:31:06 +02004#include "pythread.h"
5#include <signal.h>
6#include <object.h>
7#include <frameobject.h>
8#include <signal.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +02009#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinner7a399122014-09-30 13:40:12 +020010# include <pthread.h>
11#endif
12#ifdef MS_WINDOWS
13# include <windows.h>
14#endif
15#ifdef HAVE_SYS_RESOURCE_H
16# include <sys/resource.h>
Victor Stinner0aafa4f2011-06-29 23:28:02 +020017#endif
18
Victor Stinner8c663fd2017-11-08 14:44:44 -080019/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
20#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
Victor Stinner96994402011-04-07 11:37:19 +020021
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020022#define FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +020023
24#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020025 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
26 SIGILL can be handled by the process, and these signals can only be used
27 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020028# define FAULTHANDLER_USER
29#endif
30
Victor Stinnerc7489a52015-04-01 18:48:58 +020031#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
Victor Stinner024e37a2011-03-31 01:31:06 +020032
Victor Stinnerbd303c12013-11-07 23:07:29 +010033_Py_IDENTIFIER(enable);
34_Py_IDENTIFIER(fileno);
35_Py_IDENTIFIER(flush);
36_Py_IDENTIFIER(stderr);
37
Victor Stinner024e37a2011-03-31 01:31:06 +020038#ifdef HAVE_SIGACTION
39typedef struct sigaction _Py_sighandler_t;
40#else
41typedef PyOS_sighandler_t _Py_sighandler_t;
42#endif
43
44typedef struct {
45 int signum;
46 int enabled;
47 const char* name;
48 _Py_sighandler_t previous;
49 int all_threads;
50} fault_handler_t;
51
52static struct {
53 int enabled;
54 PyObject *file;
55 int fd;
56 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020057 PyInterpreterState *interp;
Victor Stinner46c2b812017-04-21 18:06:13 +020058#ifdef MS_WINDOWS
59 void *exc_handler;
60#endif
Victor Stinner024e37a2011-03-31 01:31:06 +020061} fatal_error = {0, NULL, -1, 0};
62
63#ifdef FAULTHANDLER_LATER
64static struct {
65 PyObject *file;
66 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020067 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020068 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020069 PyInterpreterState *interp;
70 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020071 char *header;
72 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020073 /* The main thread always holds this lock. It is only released when
74 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020075 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020076 PyThread_type_lock cancel_event;
77 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020078 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020079} thread;
80#endif
81
82#ifdef FAULTHANDLER_USER
83typedef struct {
84 int enabled;
85 PyObject *file;
86 int fd;
87 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020088 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020089 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020090 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020091} user_signal_t;
92
93static user_signal_t *user_signals;
94
95/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +020096#ifndef NSIG
97# if defined(_NSIG)
98# define NSIG _NSIG /* For BSD/SysV */
99# elif defined(_SIGMAX)
100# define NSIG (_SIGMAX + 1) /* For QNX */
101# elif defined(SIGMAX)
102# define NSIG (SIGMAX + 1) /* For djgpp */
103# else
104# define NSIG 64 /* Use a reasonable default value */
105# endif
106#endif
107
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200108static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200109#endif /* FAULTHANDLER_USER */
110
111
112static fault_handler_t faulthandler_handlers[] = {
113#ifdef SIGBUS
114 {SIGBUS, 0, "Bus error", },
115#endif
116#ifdef SIGILL
117 {SIGILL, 0, "Illegal instruction", },
118#endif
119 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200120 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200121 /* define SIGSEGV at the end to make it the default choice if searching the
122 handler fails in faulthandler_fatal_error() */
123 {SIGSEGV, 0, "Segmentation fault", }
124};
Victor Stinner404cdc52016-03-23 10:39:17 +0100125static const size_t faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200126 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200127
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100128/* Using an alternative stack requires sigaltstack()
129 and sigaction() SA_ONSTACK */
130#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
131# define FAULTHANDLER_USE_ALT_STACK
132#endif
133
134#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +0200135static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700136static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200137#endif
138
139
140/* Get the file descriptor of a file by calling its fileno() method and then
141 call its flush() method.
142
143 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100144 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200145
Victor Stinner95bb7142015-03-12 15:32:03 +0100146 On success, return the file descriptor and write the new file into *file_ptr.
147 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200148
Victor Stinner95bb7142015-03-12 15:32:03 +0100149static int
150faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200151{
152 PyObject *result;
153 long fd_long;
154 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100155 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200156
157 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100158 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200159 if (file == NULL) {
160 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100161 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200162 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200163 if (file == Py_None) {
164 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100165 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200166 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200167 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100168 else if (PyLong_Check(file)) {
169 fd = _PyLong_AsInt(file);
170 if (fd == -1 && PyErr_Occurred())
171 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700172 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100173 PyErr_SetString(PyExc_ValueError,
174 "file is not a valid file descripter");
175 return -1;
176 }
177 *file_ptr = NULL;
178 return fd;
179 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200180
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200181 result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno);
Victor Stinner024e37a2011-03-31 01:31:06 +0200182 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100183 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200184
185 fd = -1;
186 if (PyLong_Check(result)) {
187 fd_long = PyLong_AsLong(result);
188 if (0 <= fd_long && fd_long < INT_MAX)
189 fd = (int)fd_long;
190 }
191 Py_DECREF(result);
192
193 if (fd == -1) {
194 PyErr_SetString(PyExc_RuntimeError,
195 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100196 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200197 }
198
Jeroen Demeyer762f93f2019-07-08 10:19:25 +0200199 result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200200 if (result != NULL)
201 Py_DECREF(result);
202 else {
203 /* ignore flush() error */
204 PyErr_Clear();
205 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100206 *file_ptr = file;
207 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200208}
209
Victor Stinnera4de6d82011-04-09 00:47:23 +0200210/* Get the state of the current thread: only call this function if the current
211 thread holds the GIL. Raise an exception on error. */
212static PyThreadState*
213get_thread_state(void)
214{
Victor Stinner861d9ab2016-03-16 22:45:24 +0100215 PyThreadState *tstate = _PyThreadState_UncheckedGet();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200216 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100217 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200218 PyErr_SetString(PyExc_RuntimeError,
219 "unable to get the current thread state");
220 return NULL;
221 }
222 return tstate;
223}
224
Victor Stinnerc7489a52015-04-01 18:48:58 +0200225static void
226faulthandler_dump_traceback(int fd, int all_threads,
227 PyInterpreterState *interp)
228{
229 static volatile int reentrant = 0;
230 PyThreadState *tstate;
231
232 if (reentrant)
233 return;
234
235 reentrant = 1;
236
Victor Stinnerc7489a52015-04-01 18:48:58 +0200237 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
238 are thus delivered to the thread that caused the fault. Get the Python
239 thread state of the current thread.
240
241 PyThreadState_Get() doesn't give the state of the thread that caused the
242 fault if the thread released the GIL, and so this function cannot be
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900243 used. Read the thread specific storage (TSS) instead: call
Victor Stinnerc7489a52015-04-01 18:48:58 +0200244 PyGILState_GetThisThreadState(). */
245 tstate = PyGILState_GetThisThreadState();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200246
Victor Stinner861d9ab2016-03-16 22:45:24 +0100247 if (all_threads) {
248 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
249 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200250 else {
251 if (tstate != NULL)
252 _Py_DumpTraceback(fd, tstate);
253 }
254
255 reentrant = 0;
256}
257
Victor Stinner024e37a2011-03-31 01:31:06 +0200258static PyObject*
259faulthandler_dump_traceback_py(PyObject *self,
260 PyObject *args, PyObject *kwargs)
261{
262 static char *kwlist[] = {"file", "all_threads", NULL};
263 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200264 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200265 PyThreadState *tstate;
266 const char *errmsg;
267 int fd;
268
269 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
270 "|Oi:dump_traceback", kwlist,
271 &file, &all_threads))
272 return NULL;
273
Victor Stinner95bb7142015-03-12 15:32:03 +0100274 fd = faulthandler_get_fileno(&file);
275 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200276 return NULL;
277
Victor Stinnera4de6d82011-04-09 00:47:23 +0200278 tstate = get_thread_state();
279 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200280 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200281
282 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100283 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200284 if (errmsg != NULL) {
285 PyErr_SetString(PyExc_RuntimeError, errmsg);
286 return NULL;
287 }
288 }
289 else {
290 _Py_DumpTraceback(fd, tstate);
291 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200292
293 if (PyErr_CheckSignals())
294 return NULL;
295
Victor Stinner024e37a2011-03-31 01:31:06 +0200296 Py_RETURN_NONE;
297}
298
Victor Stinner404cdc52016-03-23 10:39:17 +0100299static void
300faulthandler_disable_fatal_handler(fault_handler_t *handler)
301{
302 if (!handler->enabled)
303 return;
304 handler->enabled = 0;
305#ifdef HAVE_SIGACTION
306 (void)sigaction(handler->signum, &handler->previous, NULL);
307#else
308 (void)signal(handler->signum, handler->previous);
309#endif
310}
311
Victor Stinner024e37a2011-03-31 01:31:06 +0200312
Victor Stinner410dd7d2011-05-11 20:56:08 +0200313/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200314
315 Display the current Python traceback, restore the previous handler and call
316 the previous handler.
317
Victor Stinner410dd7d2011-05-11 20:56:08 +0200318 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200319 signal handler would not be called (for an unknown reason). The execution of
320 the program continues at faulthandler_fatal_error() exit, but the same
321 instruction will raise the same fault (signal), and so the previous handler
322 will be called.
323
Victor Stinner410dd7d2011-05-11 20:56:08 +0200324 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200325
326static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200327faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200328{
329 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100330 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200331 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200332 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200333
334 if (!fatal_error.enabled)
335 return;
336
337 for (i=0; i < faulthandler_nsignals; i++) {
338 handler = &faulthandler_handlers[i];
339 if (handler->signum == signum)
340 break;
341 }
342 if (handler == NULL) {
343 /* faulthandler_nsignals == 0 (unlikely) */
344 return;
345 }
346
347 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100348 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200349
350 PUTS(fd, "Fatal Python error: ");
351 PUTS(fd, handler->name);
352 PUTS(fd, "\n\n");
353
Victor Stinnerc7489a52015-04-01 18:48:58 +0200354 faulthandler_dump_traceback(fd, fatal_error.all_threads,
355 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200356
Victor Stinnerc9256172011-05-07 12:20:11 +0200357 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200358#ifdef MS_WINDOWS
359 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200360 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200361 handler, because the Windows signal handler would not be called */
362 return;
363 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200364#endif
R David Murrayfc069992013-12-13 20:52:19 -0500365 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200366 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
367 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200368}
369
Victor Stinner404cdc52016-03-23 10:39:17 +0100370#ifdef MS_WINDOWS
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700371static int
372faulthandler_ignore_exception(DWORD code)
373{
374 /* bpo-30557: ignore exceptions which are not errors */
375 if (!(code & 0x80000000)) {
376 return 1;
377 }
378 /* bpo-31701: ignore MSC and COM exceptions
379 E0000000 + code */
380 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
381 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
382 return 1;
383 }
384 /* Interesting exception: log it with the Python traceback */
385 return 0;
386}
387
Victor Stinner404cdc52016-03-23 10:39:17 +0100388static LONG WINAPI
389faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
390{
391 const int fd = fatal_error.fd;
392 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100393 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100394
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700395 if (faulthandler_ignore_exception(code)) {
396 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100397 return EXCEPTION_CONTINUE_SEARCH;
398 }
399
400 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100401 switch (code)
402 {
403 /* only format most common errors */
404 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
405 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
406 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
407 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
408 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
409 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
410 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
411 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700412 PUTS(fd, "code 0x");
413 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100414 }
415 PUTS(fd, "\n\n");
416
417 if (code == EXCEPTION_ACCESS_VIOLATION) {
418 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200419 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100420 fault_handler_t *handler = &faulthandler_handlers[i];
421 if (handler->signum == SIGSEGV) {
422 faulthandler_disable_fatal_handler(handler);
423 break;
424 }
425 }
426 }
427
428 faulthandler_dump_traceback(fd, fatal_error.all_threads,
429 fatal_error.interp);
430
431 /* call the next exception handler */
432 return EXCEPTION_CONTINUE_SEARCH;
433}
434#endif
435
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100436
437#ifdef FAULTHANDLER_USE_ALT_STACK
438static int
439faulthandler_allocate_stack(void)
440{
441 if (stack.ss_sp != NULL) {
442 return 0;
443 }
444 /* Allocate an alternate stack for faulthandler() signal handler
445 to be able to execute a signal handler on a stack overflow error */
446 stack.ss_sp = PyMem_Malloc(stack.ss_size);
447 if (stack.ss_sp == NULL) {
448 PyErr_NoMemory();
449 return -1;
450 }
451
452 int err = sigaltstack(&stack, &old_stack);
453 if (err) {
454 /* Release the stack to retry sigaltstack() next time */
455 PyMem_Free(stack.ss_sp);
456 stack.ss_sp = NULL;
457
458 PyErr_SetFromErrno(PyExc_OSError);
459 return -1;
460 }
461 return 0;
462}
463#endif
464
465
Victor Stinnerd727e232011-04-01 12:13:55 +0200466/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200467
doko@ubuntu.combc731502016-05-18 01:06:01 +0200468static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100469faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200470{
Victor Stinner404cdc52016-03-23 10:39:17 +0100471 if (fatal_error.enabled) {
472 return 0;
473 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100474 fatal_error.enabled = 1;
475
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100476#ifdef FAULTHANDLER_USE_ALT_STACK
477 if (faulthandler_allocate_stack() < 0) {
478 return -1;
479 }
480#endif
481
Victor Stinner46c2b812017-04-21 18:06:13 +0200482 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100483 fault_handler_t *handler;
Victor Stinner928ad282016-03-23 15:19:12 +0100484 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100485
Victor Stinner928ad282016-03-23 15:19:12 +0100486 handler = &faulthandler_handlers[i];
487 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100488#ifdef HAVE_SIGACTION
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100489 struct sigaction action;
Victor Stinner404cdc52016-03-23 10:39:17 +0100490 action.sa_handler = faulthandler_fatal_error;
491 sigemptyset(&action.sa_mask);
492 /* Do not prevent the signal from being received from within
493 its own signal handler */
494 action.sa_flags = SA_NODEFER;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100495#ifdef FAULTHANDLER_USE_ALT_STACK
496 assert(stack.ss_sp != NULL);
497 /* Call the signal handler on an alternate signal stack
498 provided by sigaltstack() */
499 action.sa_flags |= SA_ONSTACK;
Victor Stinner404cdc52016-03-23 10:39:17 +0100500#endif
501 err = sigaction(handler->signum, &action, &handler->previous);
502#else
503 handler->previous = signal(handler->signum,
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100504 faulthandler_fatal_error);
Victor Stinner404cdc52016-03-23 10:39:17 +0100505 err = (handler->previous == SIG_ERR);
506#endif
507 if (err) {
508 PyErr_SetFromErrno(PyExc_RuntimeError);
509 return -1;
510 }
511
512 handler->enabled = 1;
513 }
514
515#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200516 assert(fatal_error.exc_handler == NULL);
517 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100518#endif
519 return 0;
520}
521
522static PyObject*
523faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
524{
525 static char *kwlist[] = {"file", "all_threads", NULL};
526 PyObject *file = NULL;
527 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200528 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200529 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200530
531 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
532 "|Oi:enable", kwlist, &file, &all_threads))
533 return NULL;
534
Victor Stinner95bb7142015-03-12 15:32:03 +0100535 fd = faulthandler_get_fileno(&file);
536 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200537 return NULL;
538
Victor Stinnera4de6d82011-04-09 00:47:23 +0200539 tstate = get_thread_state();
540 if (tstate == NULL)
541 return NULL;
542
Victor Stinner95bb7142015-03-12 15:32:03 +0100543 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300544 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200545 fatal_error.fd = fd;
546 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200547 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200548
Victor Stinner404cdc52016-03-23 10:39:17 +0100549 if (faulthandler_enable() < 0) {
550 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200551 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100552
Victor Stinner024e37a2011-03-31 01:31:06 +0200553 Py_RETURN_NONE;
554}
555
556static void
557faulthandler_disable(void)
558{
Victor Stinner024e37a2011-03-31 01:31:06 +0200559 if (fatal_error.enabled) {
560 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200561 for (size_t i=0; i < faulthandler_nsignals; i++) {
562 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200563 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100564 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200565 }
566 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200567#ifdef MS_WINDOWS
568 if (fatal_error.exc_handler != NULL) {
569 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
570 fatal_error.exc_handler = NULL;
571 }
572#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200573 Py_CLEAR(fatal_error.file);
574}
575
576static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530577faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200578{
579 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200580 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200581 }
582 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200583 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200584}
585
586static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530587faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200588{
589 return PyBool_FromLong(fatal_error.enabled);
590}
591
592#ifdef FAULTHANDLER_LATER
593
594static void
595faulthandler_thread(void *unused)
596{
597 PyLockStatus st;
598 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200599 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200600#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200601 sigset_t set;
602
603 /* we don't want to receive any signal */
604 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200605 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200606#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200607
608 do {
609 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200610 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200611 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200612 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200613 break;
614 }
615 /* Timeout => dump traceback */
616 assert(st == PY_LOCK_FAILURE);
617
Victor Stinnerc7489a52015-04-01 18:48:58 +0200618 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200619
Victor Stinner861d9ab2016-03-16 22:45:24 +0100620 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200621 ok = (errmsg == NULL);
622
623 if (thread.exit)
624 _exit(1);
625 } while (ok && thread.repeat);
626
627 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200628 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200629}
630
631static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200632cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200633{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200634 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200635 PyThread_release_lock(thread.cancel_event);
636
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200637 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200638 PyThread_acquire_lock(thread.running, 1);
639 PyThread_release_lock(thread.running);
640
641 /* The main thread should always hold the cancel_event lock */
642 PyThread_acquire_lock(thread.cancel_event, 1);
643
Victor Stinner024e37a2011-03-31 01:31:06 +0200644 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200645 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200646 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200647 thread.header = NULL;
648 }
649}
650
Victor Stinner93fd4782017-10-27 07:27:12 -0700651#define SEC_TO_US (1000 * 1000)
652
Victor Stinnerc790a532011-04-08 13:39:59 +0200653static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700654format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200655{
Victor Stinner93fd4782017-10-27 07:27:12 -0700656 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200657 char buffer[100];
658
Victor Stinner93fd4782017-10-27 07:27:12 -0700659 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
660 sec = (unsigned long)(us / SEC_TO_US);
661 us %= SEC_TO_US;
662
Victor Stinnerc790a532011-04-08 13:39:59 +0200663 min = sec / 60;
664 sec %= 60;
665 hour = min / 60;
666 min %= 60;
667
Victor Stinner93fd4782017-10-27 07:27:12 -0700668 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200669 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700670 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
671 hour, min, sec, (unsigned int)us);
672 }
673 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200674 PyOS_snprintf(buffer, sizeof(buffer),
675 "Timeout (%lu:%02lu:%02lu)!\n",
676 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700677 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200678 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200679}
680
681static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200682faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200683 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200684{
685 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700686 PyObject *timeout_obj;
687 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200688 int repeat = 0;
689 PyObject *file = NULL;
690 int fd;
691 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200692 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200693 char *header;
694 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200695
696 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700697 "O|iOi:dump_traceback_later", kwlist,
698 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200699 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700700
701 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
702 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200703 return NULL;
704 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700705 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200706 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200707 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
708 return NULL;
709 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700710 /* Limit to LONG_MAX seconds for format_timeout() */
711 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
712 PyErr_SetString(PyExc_OverflowError,
713 "timeout value is too large");
714 return NULL;
715 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200716
Victor Stinnera4de6d82011-04-09 00:47:23 +0200717 tstate = get_thread_state();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100718 if (tstate == NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200719 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100720 }
Victor Stinner96994402011-04-07 11:37:19 +0200721
Victor Stinner95bb7142015-03-12 15:32:03 +0100722 fd = faulthandler_get_fileno(&file);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100723 if (fd < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200724 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100725 }
726
727 if (!thread.running) {
728 thread.running = PyThread_allocate_lock();
729 if (!thread.running) {
730 return PyErr_NoMemory();
731 }
732 }
733 if (!thread.cancel_event) {
734 thread.cancel_event = PyThread_allocate_lock();
735 if (!thread.cancel_event || !thread.running) {
736 return PyErr_NoMemory();
737 }
738
739 /* cancel_event starts to be acquired: it's only released to cancel
740 the thread. */
741 PyThread_acquire_lock(thread.cancel_event, 1);
742 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200743
Victor Stinnerc790a532011-04-08 13:39:59 +0200744 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700745 header = format_timeout(timeout_us);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100746 if (header == NULL) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200747 return PyErr_NoMemory();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100748 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200749 header_len = strlen(header);
750
Victor Stinner024e37a2011-03-31 01:31:06 +0200751 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200752 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200753
Victor Stinner95bb7142015-03-12 15:32:03 +0100754 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300755 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200756 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700757 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
758 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200759 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200760 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200761 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200762 thread.header = header;
763 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200764
765 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200766 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200767
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200768 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200769 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200770 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200771 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200772 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200773 PyErr_SetString(PyExc_RuntimeError,
774 "unable to start watchdog thread");
775 return NULL;
776 }
777
778 Py_RETURN_NONE;
779}
780
781static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530782faulthandler_cancel_dump_traceback_later_py(PyObject *self,
783 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200784{
Georg Brandldeb92b52012-09-22 08:58:55 +0200785 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200786 Py_RETURN_NONE;
787}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200788#endif /* FAULTHANDLER_LATER */
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) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200916 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200917 if (user_signals == NULL)
918 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200919 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200920 }
921 user = &user_signals[signum];
922
923 if (!user->enabled) {
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100924#ifdef FAULTHANDLER_USE_ALT_STACK
925 if (faulthandler_allocate_stack() < 0) {
926 return NULL;
927 }
928#endif
929
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200930 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200931 if (err) {
932 PyErr_SetFromErrno(PyExc_OSError);
933 return NULL;
934 }
Victor Stinner8d379542013-07-02 00:14:56 +0200935
936 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200937 }
938
Victor Stinner95bb7142015-03-12 15:32:03 +0100939 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300940 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200941 user->fd = fd;
942 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200943 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200944 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200945 user->enabled = 1;
946
947 Py_RETURN_NONE;
948}
949
950static int
951faulthandler_unregister(user_signal_t *user, int signum)
952{
Victor Stinnera01ca122011-04-01 12:56:17 +0200953 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200954 return 0;
955 user->enabled = 0;
956#ifdef HAVE_SIGACTION
957 (void)sigaction(signum, &user->previous, NULL);
958#else
959 (void)signal(signum, user->previous);
960#endif
961 Py_CLEAR(user->file);
962 user->fd = -1;
963 return 1;
964}
965
966static PyObject*
967faulthandler_unregister_py(PyObject *self, PyObject *args)
968{
969 int signum;
970 user_signal_t *user;
971 int change;
972
973 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
974 return NULL;
975
Victor Stinner44378d42011-04-01 15:37:12 +0200976 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200977 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200978
Victor Stinnercfa71232011-04-08 12:48:15 +0200979 if (user_signals == NULL)
980 Py_RETURN_FALSE;
981
Victor Stinner024e37a2011-03-31 01:31:06 +0200982 user = &user_signals[signum];
983 change = faulthandler_unregister(user, signum);
984 return PyBool_FromLong(change);
985}
986#endif /* FAULTHANDLER_USER */
987
988
Victor Stinner7a399122014-09-30 13:40:12 +0200989static void
990faulthandler_suppress_crash_report(void)
991{
992#ifdef MS_WINDOWS
993 UINT mode;
994
995 /* Configure Windows to not display the Windows Error Reporting dialog */
996 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
997 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
998#endif
999
1000#ifdef HAVE_SYS_RESOURCE_H
1001 struct rlimit rl;
1002
1003 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +01001004 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +02001005 rl.rlim_cur = 0;
1006 setrlimit(RLIMIT_CORE, &rl);
1007 }
1008#endif
1009
1010#ifdef _MSC_VER
1011 /* Visual Studio: configure abort() to not display an error message nor
1012 open a popup asking to report the fault. */
1013 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1014#endif
1015}
1016
Victor Stinner024e37a2011-03-31 01:31:06 +02001017static PyObject *
1018faulthandler_read_null(PyObject *self, PyObject *args)
1019{
Victor Stinnera2477202012-01-30 00:07:43 +01001020 volatile int *x;
1021 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +01001022
Victor Stinner7a399122014-09-30 13:40:12 +02001023 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +01001024 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +02001025 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +02001026 return PyLong_FromLong(y);
1027
1028}
1029
Victor Stinner50838282014-09-30 13:54:14 +02001030static void
1031faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +02001032{
Victor Stinner7a399122014-09-30 13:40:12 +02001033 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001034#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +02001035 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
1036 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +02001037 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +02001038 SIGSEGV was raised by the kernel because of a fault, and so if the
1039 program retries to execute the same instruction, the fault will be
1040 raised again.
1041
1042 Here the fault is simulated by a fake SIGSEGV signal raised by the
1043 application. We have to raise SIGSEGV at lease twice: once for
1044 faulthandler_fatal_error(), and one more time for the previous signal
1045 handler. */
1046 while(1)
1047 raise(SIGSEGV);
1048#else
1049 raise(SIGSEGV);
1050#endif
Victor Stinner50838282014-09-30 13:54:14 +02001051}
1052
1053static PyObject *
1054faulthandler_sigsegv(PyObject *self, PyObject *args)
1055{
1056 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +01001057 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +02001058 return NULL;
1059
1060 if (release_gil) {
1061 Py_BEGIN_ALLOW_THREADS
1062 faulthandler_raise_sigsegv();
1063 Py_END_ALLOW_THREADS
1064 } else {
1065 faulthandler_raise_sigsegv();
1066 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001067 Py_RETURN_NONE;
1068}
1069
Victor Stinner861d9ab2016-03-16 22:45:24 +01001070static void
1071faulthandler_fatal_error_thread(void *plock)
1072{
Victor Stinner9a2329f2016-12-05 17:56:36 +01001073#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +01001074 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +01001075#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001076
1077 Py_FatalError("in new thread");
1078
Victor Stinner9a2329f2016-12-05 17:56:36 +01001079#ifndef __clang__
1080 /* Issue #28152: Py_FatalError() is declared with
1081 __attribute__((__noreturn__)). GCC emits a warning without
1082 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
1083 emits a warning on the return. */
1084
Victor Stinner861d9ab2016-03-16 22:45:24 +01001085 /* notify the caller that we are done */
1086 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +01001087#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001088}
1089
1090static PyObject *
1091faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1092{
1093 long thread;
1094 PyThread_type_lock lock;
1095
1096 faulthandler_suppress_crash_report();
1097
1098 lock = PyThread_allocate_lock();
1099 if (lock == NULL)
1100 return PyErr_NoMemory();
1101
1102 PyThread_acquire_lock(lock, WAIT_LOCK);
1103
1104 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1105 if (thread == -1) {
1106 PyThread_free_lock(lock);
1107 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1108 return NULL;
1109 }
1110
1111 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001112 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001113 PyThread_acquire_lock(lock, WAIT_LOCK);
1114 PyThread_release_lock(lock);
1115 PyThread_free_lock(lock);
1116
1117 Py_RETURN_NONE;
1118}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001119
Victor Stinner024e37a2011-03-31 01:31:06 +02001120static PyObject *
1121faulthandler_sigfpe(PyObject *self, PyObject *args)
1122{
1123 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1124 PowerPC. Use volatile to disable compile-time optimizations. */
1125 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001126 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001127 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001128 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1129 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001130 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001131 /* This line is never reached, but we pretend to make something with z
1132 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001133 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001134}
1135
Victor Stinnerd727e232011-04-01 12:13:55 +02001136static PyObject *
1137faulthandler_sigabrt(PyObject *self, PyObject *args)
1138{
Victor Stinner7a399122014-09-30 13:40:12 +02001139 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001140 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001141 Py_RETURN_NONE;
1142}
1143
Victor Stinner024e37a2011-03-31 01:31:06 +02001144static PyObject *
1145faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1146{
1147 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001148 int release_gil = 0;
1149 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001150 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001151 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001152 if (release_gil) {
1153 Py_BEGIN_ALLOW_THREADS
1154 Py_FatalError(message);
1155 Py_END_ALLOW_THREADS
1156 }
1157 else {
1158 Py_FatalError(message);
1159 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001160 Py_RETURN_NONE;
1161}
1162
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001163#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001164#define FAULTHANDLER_STACK_OVERFLOW
1165
Victor Stinner19276f12015-03-23 21:20:27 +01001166#ifdef __INTEL_COMPILER
1167 /* Issue #23654: Turn off ICC's tail call optimization for the
1168 * stack_overflow generator. ICC turns the recursive tail call into
1169 * a loop. */
1170# pragma intel optimization_level 0
1171#endif
1172static
Benjamin Petersonca470632016-09-06 13:47:26 -07001173uintptr_t
1174stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001175{
1176 /* allocate 4096 bytes on the stack at each call */
1177 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001178 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001179 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001180 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001181 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001182 buffer[0] = 1;
1183 buffer[4095] = 0;
1184 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001185}
1186
1187static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301188faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001189{
1190 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001191 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001192 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001193
Victor Stinner7a399122014-09-30 13:40:12 +02001194 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001195 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001196
1197 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1198 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1199 }
1200 else {
1201 lower_limit = 0;
1202 }
1203
1204 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1205 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1206 }
1207 else {
1208 upper_limit = UINTPTR_MAX;
1209 }
1210
1211 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001212 if (sp < stop)
1213 size = stop - sp;
1214 else
1215 size = sp - stop;
1216 PyErr_Format(PyExc_RuntimeError,
1217 "unable to raise a stack overflow (allocated %zu bytes "
1218 "on the stack, %zu recursive calls)",
1219 size, depth);
1220 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001221}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001222#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001223
1224
1225static int
1226faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1227{
Victor Stinner024e37a2011-03-31 01:31:06 +02001228#ifdef FAULTHANDLER_LATER
1229 Py_VISIT(thread.file);
1230#endif
1231#ifdef FAULTHANDLER_USER
1232 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001233 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001234 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001235 }
1236#endif
1237 Py_VISIT(fatal_error.file);
1238 return 0;
1239}
1240
Victor Stinner404cdc52016-03-23 10:39:17 +01001241#ifdef MS_WINDOWS
1242static PyObject *
1243faulthandler_raise_exception(PyObject *self, PyObject *args)
1244{
1245 unsigned int code, flags = 0;
1246 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1247 return NULL;
1248 faulthandler_suppress_crash_report();
1249 RaiseException(code, flags, 0, NULL);
1250 Py_RETURN_NONE;
1251}
1252#endif
1253
Victor Stinner024e37a2011-03-31 01:31:06 +02001254PyDoc_STRVAR(module_doc,
1255"faulthandler module.");
1256
1257static PyMethodDef module_methods[] = {
1258 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001259 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001260 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001261 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301262 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001263 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301264 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001265 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1266 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001267 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001268 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001269 "dump the traceback of the current thread, or of all threads "
1270 "if all_threads is True, into file")},
1271#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001272 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001273 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001274 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001275 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001276 "or each timeout seconds if repeat is True. If exit is True, "
1277 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001278 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301279 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001280 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1281 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001282#endif
1283
1284#ifdef FAULTHANDLER_USER
1285 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001286 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001287 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001288 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001289 "traceback of the current thread, or of all threads if "
1290 "all_threads is True, into file")},
1291 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001292 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001293 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1294 "'signum' registered by register()")},
1295#endif
1296
Victor Stinner50838282014-09-30 13:54:14 +02001297 {"_read_null", faulthandler_read_null, METH_NOARGS,
1298 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001299 "a SIGSEGV or SIGBUS signal depending on the platform")},
1300 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001301 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001302 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1303 PyDoc_STR("fatal_error_c_thread(): "
1304 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001305 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001306 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001307 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1308 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001309 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1310 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001311#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301312 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001313 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1314#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001315#ifdef MS_WINDOWS
1316 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1317 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1318#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001319 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001320};
1321
1322static struct PyModuleDef module_def = {
1323 PyModuleDef_HEAD_INIT,
1324 "faulthandler",
1325 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001326 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001327 module_methods,
1328 NULL,
1329 faulthandler_traverse,
1330 NULL,
1331 NULL
1332};
1333
1334PyMODINIT_FUNC
1335PyInit_faulthandler(void)
1336{
Victor Stinner404cdc52016-03-23 10:39:17 +01001337 PyObject *m = PyModule_Create(&module_def);
1338 if (m == NULL)
1339 return NULL;
1340
1341 /* Add constants for unit tests */
1342#ifdef MS_WINDOWS
1343 /* RaiseException() codes (prefixed by an underscore) */
1344 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1345 EXCEPTION_ACCESS_VIOLATION))
1346 return NULL;
1347 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1348 EXCEPTION_INT_DIVIDE_BY_ZERO))
1349 return NULL;
1350 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1351 EXCEPTION_STACK_OVERFLOW))
1352 return NULL;
1353
1354 /* RaiseException() flags (prefixed by an underscore) */
1355 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1356 EXCEPTION_NONCONTINUABLE))
1357 return NULL;
1358 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1359 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1360 return NULL;
1361#endif
1362
1363 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001364}
1365
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001366static int
1367faulthandler_init_enable(void)
1368{
1369 PyObject *module = PyImport_ImportModule("faulthandler");
1370 if (module == NULL) {
1371 return -1;
1372 }
1373
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001374 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001375 Py_DECREF(module);
1376 if (res == NULL) {
1377 return -1;
1378 }
1379 Py_DECREF(res);
1380
1381 return 0;
1382}
1383
Victor Stinner331a6a52019-05-27 16:39:22 +02001384PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001385_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001386{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001387#ifdef FAULTHANDLER_USE_ALT_STACK
1388 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001389 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001390 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1391 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1392 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1393 platforms. */
1394 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001395#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001396
Victor Stinner024e37a2011-03-31 01:31:06 +02001397#ifdef FAULTHANDLER_LATER
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001398 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001399#endif
1400
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001401 if (enable) {
1402 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001403 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001404 }
1405 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001406 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001407}
1408
1409void _PyFaulthandler_Fini(void)
1410{
Victor Stinner024e37a2011-03-31 01:31:06 +02001411#ifdef FAULTHANDLER_LATER
1412 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001413 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001414 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001415 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001416 PyThread_free_lock(thread.cancel_event);
1417 thread.cancel_event = NULL;
1418 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001419 if (thread.running) {
1420 PyThread_free_lock(thread.running);
1421 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001422 }
1423#endif
1424
1425#ifdef FAULTHANDLER_USER
1426 /* user */
1427 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001428 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001429 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001430 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001431 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001432 user_signals = NULL;
1433 }
1434#endif
1435
1436 /* fatal */
1437 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001438
1439#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001440 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001441 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001442 stack_t current_stack;
1443 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001444 if (sigaltstack(NULL, &current_stack) == 0) {
1445 if (current_stack.ss_sp == stack.ss_sp) {
1446 /* The current alt stack is the one that we installed.
1447 It is safe to restore the old stack that we found when
1448 we installed ours */
1449 sigaltstack(&old_stack, NULL);
1450 } else {
1451 /* Someone switched to a different alt stack and didn't
1452 restore ours when they were done (if they're done).
1453 There's not much we can do in this unlikely case */
1454 }
1455 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001456 PyMem_Free(stack.ss_sp);
1457 stack.ss_sp = NULL;
1458 }
1459#endif
1460}