blob: 011ab5fa28f256185415e726ea41396fc755e831 [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{
Thomas A Caswelle2783352019-08-29 12:30:04 -0400634 /* If not scheduled, nothing to cancel */
635 if (!thread.cancel_event) {
636 return;
637 }
638
Victor Stinner410dd7d2011-05-11 20:56:08 +0200639 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200640 PyThread_release_lock(thread.cancel_event);
641
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200642 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200643 PyThread_acquire_lock(thread.running, 1);
644 PyThread_release_lock(thread.running);
645
646 /* The main thread should always hold the cancel_event lock */
647 PyThread_acquire_lock(thread.cancel_event, 1);
648
Victor Stinner024e37a2011-03-31 01:31:06 +0200649 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200650 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200651 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200652 thread.header = NULL;
653 }
654}
655
Victor Stinner93fd4782017-10-27 07:27:12 -0700656#define SEC_TO_US (1000 * 1000)
657
Victor Stinnerc790a532011-04-08 13:39:59 +0200658static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700659format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200660{
Victor Stinner93fd4782017-10-27 07:27:12 -0700661 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200662 char buffer[100];
663
Victor Stinner93fd4782017-10-27 07:27:12 -0700664 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
665 sec = (unsigned long)(us / SEC_TO_US);
666 us %= SEC_TO_US;
667
Victor Stinnerc790a532011-04-08 13:39:59 +0200668 min = sec / 60;
669 sec %= 60;
670 hour = min / 60;
671 min %= 60;
672
Victor Stinner93fd4782017-10-27 07:27:12 -0700673 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200674 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700675 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
676 hour, min, sec, (unsigned int)us);
677 }
678 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200679 PyOS_snprintf(buffer, sizeof(buffer),
680 "Timeout (%lu:%02lu:%02lu)!\n",
681 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700682 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200683 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200684}
685
686static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200687faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200688 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200689{
690 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700691 PyObject *timeout_obj;
692 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200693 int repeat = 0;
694 PyObject *file = NULL;
695 int fd;
696 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200697 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200698 char *header;
699 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200700
701 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700702 "O|iOi:dump_traceback_later", kwlist,
703 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200704 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700705
706 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
707 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200708 return NULL;
709 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700710 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200711 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200712 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
713 return NULL;
714 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700715 /* Limit to LONG_MAX seconds for format_timeout() */
716 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
717 PyErr_SetString(PyExc_OverflowError,
718 "timeout value is too large");
719 return NULL;
720 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200721
Victor Stinnera4de6d82011-04-09 00:47:23 +0200722 tstate = get_thread_state();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100723 if (tstate == NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200724 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100725 }
Victor Stinner96994402011-04-07 11:37:19 +0200726
Victor Stinner95bb7142015-03-12 15:32:03 +0100727 fd = faulthandler_get_fileno(&file);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100728 if (fd < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200729 return NULL;
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100730 }
731
732 if (!thread.running) {
733 thread.running = PyThread_allocate_lock();
734 if (!thread.running) {
735 return PyErr_NoMemory();
736 }
737 }
738 if (!thread.cancel_event) {
739 thread.cancel_event = PyThread_allocate_lock();
740 if (!thread.cancel_event || !thread.running) {
741 return PyErr_NoMemory();
742 }
743
744 /* cancel_event starts to be acquired: it's only released to cancel
745 the thread. */
746 PyThread_acquire_lock(thread.cancel_event, 1);
747 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200748
Victor Stinnerc790a532011-04-08 13:39:59 +0200749 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700750 header = format_timeout(timeout_us);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100751 if (header == NULL) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200752 return PyErr_NoMemory();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100753 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200754 header_len = strlen(header);
755
Victor Stinner024e37a2011-03-31 01:31:06 +0200756 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200757 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200758
Victor Stinner95bb7142015-03-12 15:32:03 +0100759 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300760 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200761 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700762 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
763 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200764 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200765 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200766 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200767 thread.header = header;
768 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200769
770 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200771 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200772
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200773 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200774 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200775 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200776 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200777 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200778 PyErr_SetString(PyExc_RuntimeError,
779 "unable to start watchdog thread");
780 return NULL;
781 }
782
783 Py_RETURN_NONE;
784}
785
786static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530787faulthandler_cancel_dump_traceback_later_py(PyObject *self,
788 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200789{
Georg Brandldeb92b52012-09-22 08:58:55 +0200790 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200791 Py_RETURN_NONE;
792}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200793#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200794
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100795
Victor Stinner024e37a2011-03-31 01:31:06 +0200796#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200797static int
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100798faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200799{
800#ifdef HAVE_SIGACTION
801 struct sigaction action;
802 action.sa_handler = faulthandler_user;
803 sigemptyset(&action.sa_mask);
804 /* if the signal is received while the kernel is executing a system
805 call, try to restart the system call instead of interrupting it and
806 return EINTR. */
807 action.sa_flags = SA_RESTART;
808 if (chain) {
809 /* do not prevent the signal from being received from within its
810 own signal handler */
811 action.sa_flags = SA_NODEFER;
812 }
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100813#ifdef FAULTHANDLER_USE_ALT_STACK
814 assert(stack.ss_sp != NULL);
815 /* Call the signal handler on an alternate signal stack
816 provided by sigaltstack() */
817 action.sa_flags |= SA_ONSTACK;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200818#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100819 return sigaction(signum, &action, previous_p);
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200820#else
821 _Py_sighandler_t previous;
822 previous = signal(signum, faulthandler_user);
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100823 if (previous_p != NULL) {
824 *previous_p = previous;
825 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200826 return (previous == SIG_ERR);
827#endif
828}
829
Victor Stinner024e37a2011-03-31 01:31:06 +0200830/* Handler of user signals (e.g. SIGUSR1).
831
832 Dump the traceback of the current thread, or of all threads if
833 thread.all_threads is true.
834
835 This function is signal safe and should only call signal safe functions. */
836
837static void
838faulthandler_user(int signum)
839{
840 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200841 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200842
843 user = &user_signals[signum];
844 if (!user->enabled)
845 return;
846
Victor Stinnerc7489a52015-04-01 18:48:58 +0200847 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200848
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200849#ifdef HAVE_SIGACTION
850 if (user->chain) {
851 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200852 errno = save_errno;
853
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200854 /* call the previous signal handler */
855 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200856
857 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200858 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200859 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200860 }
861#else
862 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200863 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200864 /* call the previous signal handler */
865 user->previous(signum);
866 }
867#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200868}
869
870static int
871check_signum(int signum)
872{
Victor Stinner46c2b812017-04-21 18:06:13 +0200873 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200874 if (faulthandler_handlers[i].signum == signum) {
875 PyErr_Format(PyExc_RuntimeError,
876 "signal %i cannot be registered, "
877 "use enable() instead",
878 signum);
879 return 0;
880 }
881 }
882 if (signum < 1 || NSIG <= signum) {
883 PyErr_SetString(PyExc_ValueError, "signal number out of range");
884 return 0;
885 }
886 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200887}
888
889static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200890faulthandler_register_py(PyObject *self,
891 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200892{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200893 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200894 int signum;
895 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200896 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200897 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200898 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200899 user_signal_t *user;
900 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200901 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200902 int err;
903
904 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200905 "i|Oii:register", kwlist,
906 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200907 return NULL;
908
Victor Stinner44378d42011-04-01 15:37:12 +0200909 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200910 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200911
Victor Stinnera4de6d82011-04-09 00:47:23 +0200912 tstate = get_thread_state();
913 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200914 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200915
Victor Stinner95bb7142015-03-12 15:32:03 +0100916 fd = faulthandler_get_fileno(&file);
917 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200918 return NULL;
919
920 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200921 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200922 if (user_signals == NULL)
923 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200924 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200925 }
926 user = &user_signals[signum];
927
928 if (!user->enabled) {
Victor Stinnerd8c5adf2019-08-21 13:40:42 +0100929#ifdef FAULTHANDLER_USE_ALT_STACK
930 if (faulthandler_allocate_stack() < 0) {
931 return NULL;
932 }
933#endif
934
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200935 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200936 if (err) {
937 PyErr_SetFromErrno(PyExc_OSError);
938 return NULL;
939 }
Victor Stinner8d379542013-07-02 00:14:56 +0200940
941 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200942 }
943
Victor Stinner95bb7142015-03-12 15:32:03 +0100944 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300945 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200946 user->fd = fd;
947 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200948 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200949 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200950 user->enabled = 1;
951
952 Py_RETURN_NONE;
953}
954
955static int
956faulthandler_unregister(user_signal_t *user, int signum)
957{
Victor Stinnera01ca122011-04-01 12:56:17 +0200958 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200959 return 0;
960 user->enabled = 0;
961#ifdef HAVE_SIGACTION
962 (void)sigaction(signum, &user->previous, NULL);
963#else
964 (void)signal(signum, user->previous);
965#endif
966 Py_CLEAR(user->file);
967 user->fd = -1;
968 return 1;
969}
970
971static PyObject*
972faulthandler_unregister_py(PyObject *self, PyObject *args)
973{
974 int signum;
975 user_signal_t *user;
976 int change;
977
978 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
979 return NULL;
980
Victor Stinner44378d42011-04-01 15:37:12 +0200981 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200982 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200983
Victor Stinnercfa71232011-04-08 12:48:15 +0200984 if (user_signals == NULL)
985 Py_RETURN_FALSE;
986
Victor Stinner024e37a2011-03-31 01:31:06 +0200987 user = &user_signals[signum];
988 change = faulthandler_unregister(user, signum);
989 return PyBool_FromLong(change);
990}
991#endif /* FAULTHANDLER_USER */
992
993
Victor Stinner7a399122014-09-30 13:40:12 +0200994static void
995faulthandler_suppress_crash_report(void)
996{
997#ifdef MS_WINDOWS
998 UINT mode;
999
1000 /* Configure Windows to not display the Windows Error Reporting dialog */
1001 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
1002 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
1003#endif
1004
1005#ifdef HAVE_SYS_RESOURCE_H
1006 struct rlimit rl;
1007
1008 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +01001009 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +02001010 rl.rlim_cur = 0;
1011 setrlimit(RLIMIT_CORE, &rl);
1012 }
1013#endif
1014
1015#ifdef _MSC_VER
1016 /* Visual Studio: configure abort() to not display an error message nor
1017 open a popup asking to report the fault. */
1018 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1019#endif
1020}
1021
Victor Stinner024e37a2011-03-31 01:31:06 +02001022static PyObject *
1023faulthandler_read_null(PyObject *self, PyObject *args)
1024{
Victor Stinnera2477202012-01-30 00:07:43 +01001025 volatile int *x;
1026 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +01001027
Victor Stinner7a399122014-09-30 13:40:12 +02001028 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +01001029 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +02001030 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +02001031 return PyLong_FromLong(y);
1032
1033}
1034
Victor Stinner50838282014-09-30 13:54:14 +02001035static void
1036faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +02001037{
Victor Stinner7a399122014-09-30 13:40:12 +02001038 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001039#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +02001040 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
1041 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +02001042 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +02001043 SIGSEGV was raised by the kernel because of a fault, and so if the
1044 program retries to execute the same instruction, the fault will be
1045 raised again.
1046
1047 Here the fault is simulated by a fake SIGSEGV signal raised by the
1048 application. We have to raise SIGSEGV at lease twice: once for
1049 faulthandler_fatal_error(), and one more time for the previous signal
1050 handler. */
1051 while(1)
1052 raise(SIGSEGV);
1053#else
1054 raise(SIGSEGV);
1055#endif
Victor Stinner50838282014-09-30 13:54:14 +02001056}
1057
1058static PyObject *
1059faulthandler_sigsegv(PyObject *self, PyObject *args)
1060{
1061 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +01001062 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +02001063 return NULL;
1064
1065 if (release_gil) {
1066 Py_BEGIN_ALLOW_THREADS
1067 faulthandler_raise_sigsegv();
1068 Py_END_ALLOW_THREADS
1069 } else {
1070 faulthandler_raise_sigsegv();
1071 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001072 Py_RETURN_NONE;
1073}
1074
Victor Stinner861d9ab2016-03-16 22:45:24 +01001075static void
1076faulthandler_fatal_error_thread(void *plock)
1077{
Victor Stinner9a2329f2016-12-05 17:56:36 +01001078#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +01001079 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +01001080#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001081
1082 Py_FatalError("in new thread");
1083
Victor Stinner9a2329f2016-12-05 17:56:36 +01001084#ifndef __clang__
1085 /* Issue #28152: Py_FatalError() is declared with
1086 __attribute__((__noreturn__)). GCC emits a warning without
1087 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
1088 emits a warning on the return. */
1089
Victor Stinner861d9ab2016-03-16 22:45:24 +01001090 /* notify the caller that we are done */
1091 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +01001092#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001093}
1094
1095static PyObject *
1096faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1097{
1098 long thread;
1099 PyThread_type_lock lock;
1100
1101 faulthandler_suppress_crash_report();
1102
1103 lock = PyThread_allocate_lock();
1104 if (lock == NULL)
1105 return PyErr_NoMemory();
1106
1107 PyThread_acquire_lock(lock, WAIT_LOCK);
1108
1109 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1110 if (thread == -1) {
1111 PyThread_free_lock(lock);
1112 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1113 return NULL;
1114 }
1115
1116 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001117 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001118 PyThread_acquire_lock(lock, WAIT_LOCK);
1119 PyThread_release_lock(lock);
1120 PyThread_free_lock(lock);
1121
1122 Py_RETURN_NONE;
1123}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001124
Victor Stinner024e37a2011-03-31 01:31:06 +02001125static PyObject *
1126faulthandler_sigfpe(PyObject *self, PyObject *args)
1127{
1128 /* 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;
Victor Stinner7a399122014-09-30 13:40:12 +02001131 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001132 z = x / y;
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 Stinner410dd7d2011-05-11 20:56:08 +02001136 /* This line is never reached, but we pretend to make something with z
1137 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001138 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001139}
1140
Victor Stinnerd727e232011-04-01 12:13:55 +02001141static PyObject *
1142faulthandler_sigabrt(PyObject *self, PyObject *args)
1143{
Victor Stinner7a399122014-09-30 13:40:12 +02001144 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001145 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001146 Py_RETURN_NONE;
1147}
1148
Victor Stinner024e37a2011-03-31 01:31:06 +02001149static PyObject *
1150faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1151{
1152 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001153 int release_gil = 0;
1154 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001155 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001156 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001157 if (release_gil) {
1158 Py_BEGIN_ALLOW_THREADS
1159 Py_FatalError(message);
1160 Py_END_ALLOW_THREADS
1161 }
1162 else {
1163 Py_FatalError(message);
1164 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001165 Py_RETURN_NONE;
1166}
1167
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001168#if defined(FAULTHANDLER_USE_ALT_STACK)
Victor Stinner404cdc52016-03-23 10:39:17 +01001169#define FAULTHANDLER_STACK_OVERFLOW
1170
Victor Stinner19276f12015-03-23 21:20:27 +01001171#ifdef __INTEL_COMPILER
1172 /* Issue #23654: Turn off ICC's tail call optimization for the
1173 * stack_overflow generator. ICC turns the recursive tail call into
1174 * a loop. */
1175# pragma intel optimization_level 0
1176#endif
1177static
Benjamin Petersonca470632016-09-06 13:47:26 -07001178uintptr_t
1179stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001180{
1181 /* allocate 4096 bytes on the stack at each call */
1182 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001183 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001184 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001185 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001186 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001187 buffer[0] = 1;
1188 buffer[4095] = 0;
1189 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001190}
1191
1192static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301193faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001194{
1195 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001196 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001197 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001198
Victor Stinner7a399122014-09-30 13:40:12 +02001199 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001200 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001201
1202 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1203 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1204 }
1205 else {
1206 lower_limit = 0;
1207 }
1208
1209 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1210 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1211 }
1212 else {
1213 upper_limit = UINTPTR_MAX;
1214 }
1215
1216 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001217 if (sp < stop)
1218 size = stop - sp;
1219 else
1220 size = sp - stop;
1221 PyErr_Format(PyExc_RuntimeError,
1222 "unable to raise a stack overflow (allocated %zu bytes "
1223 "on the stack, %zu recursive calls)",
1224 size, depth);
1225 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001226}
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001227#endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001228
1229
1230static int
1231faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1232{
Victor Stinner024e37a2011-03-31 01:31:06 +02001233#ifdef FAULTHANDLER_LATER
1234 Py_VISIT(thread.file);
1235#endif
1236#ifdef FAULTHANDLER_USER
1237 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001238 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001239 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001240 }
1241#endif
1242 Py_VISIT(fatal_error.file);
1243 return 0;
1244}
1245
Victor Stinner404cdc52016-03-23 10:39:17 +01001246#ifdef MS_WINDOWS
1247static PyObject *
1248faulthandler_raise_exception(PyObject *self, PyObject *args)
1249{
1250 unsigned int code, flags = 0;
1251 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1252 return NULL;
1253 faulthandler_suppress_crash_report();
1254 RaiseException(code, flags, 0, NULL);
1255 Py_RETURN_NONE;
1256}
1257#endif
1258
Victor Stinner024e37a2011-03-31 01:31:06 +02001259PyDoc_STRVAR(module_doc,
1260"faulthandler module.");
1261
1262static PyMethodDef module_methods[] = {
1263 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001264 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001265 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001266 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301267 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001268 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301269 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001270 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1271 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001272 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001273 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001274 "dump the traceback of the current thread, or of all threads "
1275 "if all_threads is True, into file")},
1276#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001277 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001278 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001279 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001280 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001281 "or each timeout seconds if repeat is True. If exit is True, "
1282 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001283 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301284 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001285 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1286 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001287#endif
1288
1289#ifdef FAULTHANDLER_USER
1290 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001291 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001292 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001293 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001294 "traceback of the current thread, or of all threads if "
1295 "all_threads is True, into file")},
1296 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001297 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001298 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1299 "'signum' registered by register()")},
1300#endif
1301
Victor Stinner50838282014-09-30 13:54:14 +02001302 {"_read_null", faulthandler_read_null, METH_NOARGS,
1303 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001304 "a SIGSEGV or SIGBUS signal depending on the platform")},
1305 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001306 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001307 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1308 PyDoc_STR("fatal_error_c_thread(): "
1309 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001310 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001311 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001312 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1313 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001314 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1315 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001316#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301317 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001318 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1319#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001320#ifdef MS_WINDOWS
1321 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1322 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1323#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001324 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001325};
1326
1327static struct PyModuleDef module_def = {
1328 PyModuleDef_HEAD_INIT,
1329 "faulthandler",
1330 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001331 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001332 module_methods,
1333 NULL,
1334 faulthandler_traverse,
1335 NULL,
1336 NULL
1337};
1338
1339PyMODINIT_FUNC
1340PyInit_faulthandler(void)
1341{
Victor Stinner404cdc52016-03-23 10:39:17 +01001342 PyObject *m = PyModule_Create(&module_def);
1343 if (m == NULL)
1344 return NULL;
1345
1346 /* Add constants for unit tests */
1347#ifdef MS_WINDOWS
1348 /* RaiseException() codes (prefixed by an underscore) */
1349 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1350 EXCEPTION_ACCESS_VIOLATION))
1351 return NULL;
1352 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1353 EXCEPTION_INT_DIVIDE_BY_ZERO))
1354 return NULL;
1355 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1356 EXCEPTION_STACK_OVERFLOW))
1357 return NULL;
1358
1359 /* RaiseException() flags (prefixed by an underscore) */
1360 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1361 EXCEPTION_NONCONTINUABLE))
1362 return NULL;
1363 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1364 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1365 return NULL;
1366#endif
1367
1368 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001369}
1370
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001371static int
1372faulthandler_init_enable(void)
1373{
1374 PyObject *module = PyImport_ImportModule("faulthandler");
1375 if (module == NULL) {
1376 return -1;
1377 }
1378
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001379 PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable);
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001380 Py_DECREF(module);
1381 if (res == NULL) {
1382 return -1;
1383 }
1384 Py_DECREF(res);
1385
1386 return 0;
1387}
1388
Victor Stinner331a6a52019-05-27 16:39:22 +02001389PyStatus
Victor Stinnera7368ac2017-11-15 18:11:45 -08001390_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001391{
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001392#ifdef FAULTHANDLER_USE_ALT_STACK
1393 memset(&stack, 0, sizeof(stack));
Victor Stinner024e37a2011-03-31 01:31:06 +02001394 stack.ss_flags = 0;
Victor Stinnerac827ed2019-08-14 23:35:27 +02001395 /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
1396 SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
1397 signal handler uses more than SIGSTKSZ bytes of stack memory on some
1398 platforms. */
1399 stack.ss_size = SIGSTKSZ * 2;
Victor Stinner024e37a2011-03-31 01:31:06 +02001400#endif
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001401
Victor Stinner024e37a2011-03-31 01:31:06 +02001402#ifdef FAULTHANDLER_LATER
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001403 memset(&thread, 0, sizeof(thread));
Victor Stinner024e37a2011-03-31 01:31:06 +02001404#endif
1405
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001406 if (enable) {
1407 if (faulthandler_init_enable() < 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +02001408 return _PyStatus_ERR("failed to enable faulthandler");
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001409 }
1410 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001411 return _PyStatus_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001412}
1413
1414void _PyFaulthandler_Fini(void)
1415{
Victor Stinner024e37a2011-03-31 01:31:06 +02001416#ifdef FAULTHANDLER_LATER
1417 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001418 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001419 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001420 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001421 PyThread_free_lock(thread.cancel_event);
1422 thread.cancel_event = NULL;
1423 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001424 if (thread.running) {
1425 PyThread_free_lock(thread.running);
1426 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001427 }
1428#endif
1429
1430#ifdef FAULTHANDLER_USER
1431 /* user */
1432 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001433 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001434 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001435 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001436 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001437 user_signals = NULL;
1438 }
1439#endif
1440
1441 /* fatal */
1442 faulthandler_disable();
Victor Stinnerd8c5adf2019-08-21 13:40:42 +01001443
1444#ifdef FAULTHANDLER_USE_ALT_STACK
Victor Stinner024e37a2011-03-31 01:31:06 +02001445 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001446 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001447 stack_t current_stack;
1448 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001449 if (sigaltstack(NULL, &current_stack) == 0) {
1450 if (current_stack.ss_sp == stack.ss_sp) {
1451 /* The current alt stack is the one that we installed.
1452 It is safe to restore the old stack that we found when
1453 we installed ours */
1454 sigaltstack(&old_stack, NULL);
1455 } else {
1456 /* Someone switched to a different alt stack and didn't
1457 restore ours when they were done (if they're done).
1458 There's not much we can do in this unlikely case */
1459 }
1460 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001461 PyMem_Free(stack.ss_sp);
1462 stack.ss_sp = NULL;
1463 }
1464#endif
1465}