blob: aa466c46ccff12632f01e62132b941f8b0b9d2cd [file] [log] [blame]
Victor Stinner024e37a2011-03-31 01:31:06 +02001#include "Python.h"
Victor Stinner871ff772019-05-17 23:54:00 +02002#include "pycore_coreconfig.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
128#ifdef HAVE_SIGALTSTACK
129static stack_t stack;
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -0700130static stack_t old_stack;
Victor Stinner024e37a2011-03-31 01:31:06 +0200131#endif
132
133
134/* Get the file descriptor of a file by calling its fileno() method and then
135 call its flush() method.
136
137 If file is NULL or Py_None, use sys.stderr as the new file.
Victor Stinner95bb7142015-03-12 15:32:03 +0100138 If file is an integer, it will be treated as file descriptor.
Victor Stinner024e37a2011-03-31 01:31:06 +0200139
Victor Stinner95bb7142015-03-12 15:32:03 +0100140 On success, return the file descriptor and write the new file into *file_ptr.
141 On error, return -1. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200142
Victor Stinner95bb7142015-03-12 15:32:03 +0100143static int
144faulthandler_get_fileno(PyObject **file_ptr)
Victor Stinner024e37a2011-03-31 01:31:06 +0200145{
146 PyObject *result;
147 long fd_long;
148 int fd;
Victor Stinner95bb7142015-03-12 15:32:03 +0100149 PyObject *file = *file_ptr;
Victor Stinner024e37a2011-03-31 01:31:06 +0200150
151 if (file == NULL || file == Py_None) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100152 file = _PySys_GetObjectId(&PyId_stderr);
Victor Stinner024e37a2011-03-31 01:31:06 +0200153 if (file == NULL) {
154 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
Victor Stinner95bb7142015-03-12 15:32:03 +0100155 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200156 }
Victor Stinnere2d66902014-05-14 17:15:50 +0200157 if (file == Py_None) {
158 PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Victor Stinner95bb7142015-03-12 15:32:03 +0100159 return -1;
Victor Stinnere2d66902014-05-14 17:15:50 +0200160 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200161 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100162 else if (PyLong_Check(file)) {
163 fd = _PyLong_AsInt(file);
164 if (fd == -1 && PyErr_Occurred())
165 return -1;
Steve Dower940f33a2016-09-08 11:21:54 -0700166 if (fd < 0) {
Victor Stinner95bb7142015-03-12 15:32:03 +0100167 PyErr_SetString(PyExc_ValueError,
168 "file is not a valid file descripter");
169 return -1;
170 }
171 *file_ptr = NULL;
172 return fd;
173 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200174
Victor Stinner3466bde2016-09-05 18:16:01 -0700175 result = _PyObject_CallMethodId(file, &PyId_fileno, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200176 if (result == NULL)
Victor Stinner95bb7142015-03-12 15:32:03 +0100177 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200178
179 fd = -1;
180 if (PyLong_Check(result)) {
181 fd_long = PyLong_AsLong(result);
182 if (0 <= fd_long && fd_long < INT_MAX)
183 fd = (int)fd_long;
184 }
185 Py_DECREF(result);
186
187 if (fd == -1) {
188 PyErr_SetString(PyExc_RuntimeError,
189 "file.fileno() is not a valid file descriptor");
Victor Stinner95bb7142015-03-12 15:32:03 +0100190 return -1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200191 }
192
Victor Stinner3466bde2016-09-05 18:16:01 -0700193 result = _PyObject_CallMethodId(file, &PyId_flush, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200194 if (result != NULL)
195 Py_DECREF(result);
196 else {
197 /* ignore flush() error */
198 PyErr_Clear();
199 }
Victor Stinner95bb7142015-03-12 15:32:03 +0100200 *file_ptr = file;
201 return fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200202}
203
Victor Stinnera4de6d82011-04-09 00:47:23 +0200204/* Get the state of the current thread: only call this function if the current
205 thread holds the GIL. Raise an exception on error. */
206static PyThreadState*
207get_thread_state(void)
208{
Victor Stinner861d9ab2016-03-16 22:45:24 +0100209 PyThreadState *tstate = _PyThreadState_UncheckedGet();
Victor Stinnera4de6d82011-04-09 00:47:23 +0200210 if (tstate == NULL) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100211 /* just in case but very unlikely... */
Victor Stinnera4de6d82011-04-09 00:47:23 +0200212 PyErr_SetString(PyExc_RuntimeError,
213 "unable to get the current thread state");
214 return NULL;
215 }
216 return tstate;
217}
218
Victor Stinnerc7489a52015-04-01 18:48:58 +0200219static void
220faulthandler_dump_traceback(int fd, int all_threads,
221 PyInterpreterState *interp)
222{
223 static volatile int reentrant = 0;
224 PyThreadState *tstate;
225
226 if (reentrant)
227 return;
228
229 reentrant = 1;
230
Victor Stinnerc7489a52015-04-01 18:48:58 +0200231 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
232 are thus delivered to the thread that caused the fault. Get the Python
233 thread state of the current thread.
234
235 PyThreadState_Get() doesn't give the state of the thread that caused the
236 fault if the thread released the GIL, and so this function cannot be
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900237 used. Read the thread specific storage (TSS) instead: call
Victor Stinnerc7489a52015-04-01 18:48:58 +0200238 PyGILState_GetThisThreadState(). */
239 tstate = PyGILState_GetThisThreadState();
Victor Stinnerc7489a52015-04-01 18:48:58 +0200240
Victor Stinner861d9ab2016-03-16 22:45:24 +0100241 if (all_threads) {
242 (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
243 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200244 else {
245 if (tstate != NULL)
246 _Py_DumpTraceback(fd, tstate);
247 }
248
249 reentrant = 0;
250}
251
Victor Stinner024e37a2011-03-31 01:31:06 +0200252static PyObject*
253faulthandler_dump_traceback_py(PyObject *self,
254 PyObject *args, PyObject *kwargs)
255{
256 static char *kwlist[] = {"file", "all_threads", NULL};
257 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200258 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200259 PyThreadState *tstate;
260 const char *errmsg;
261 int fd;
262
263 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
264 "|Oi:dump_traceback", kwlist,
265 &file, &all_threads))
266 return NULL;
267
Victor Stinner95bb7142015-03-12 15:32:03 +0100268 fd = faulthandler_get_fileno(&file);
269 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200270 return NULL;
271
Victor Stinnera4de6d82011-04-09 00:47:23 +0200272 tstate = get_thread_state();
273 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200274 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200275
276 if (all_threads) {
Victor Stinner861d9ab2016-03-16 22:45:24 +0100277 errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
Victor Stinner024e37a2011-03-31 01:31:06 +0200278 if (errmsg != NULL) {
279 PyErr_SetString(PyExc_RuntimeError, errmsg);
280 return NULL;
281 }
282 }
283 else {
284 _Py_DumpTraceback(fd, tstate);
285 }
Victor Stinnerc7489a52015-04-01 18:48:58 +0200286
287 if (PyErr_CheckSignals())
288 return NULL;
289
Victor Stinner024e37a2011-03-31 01:31:06 +0200290 Py_RETURN_NONE;
291}
292
Victor Stinner404cdc52016-03-23 10:39:17 +0100293static void
294faulthandler_disable_fatal_handler(fault_handler_t *handler)
295{
296 if (!handler->enabled)
297 return;
298 handler->enabled = 0;
299#ifdef HAVE_SIGACTION
300 (void)sigaction(handler->signum, &handler->previous, NULL);
301#else
302 (void)signal(handler->signum, handler->previous);
303#endif
304}
305
Victor Stinner024e37a2011-03-31 01:31:06 +0200306
Victor Stinner410dd7d2011-05-11 20:56:08 +0200307/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200308
309 Display the current Python traceback, restore the previous handler and call
310 the previous handler.
311
Victor Stinner410dd7d2011-05-11 20:56:08 +0200312 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200313 signal handler would not be called (for an unknown reason). The execution of
314 the program continues at faulthandler_fatal_error() exit, but the same
315 instruction will raise the same fault (signal), and so the previous handler
316 will be called.
317
Victor Stinner410dd7d2011-05-11 20:56:08 +0200318 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200319
320static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200321faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200322{
323 const int fd = fatal_error.fd;
Victor Stinner404cdc52016-03-23 10:39:17 +0100324 size_t i;
Victor Stinner024e37a2011-03-31 01:31:06 +0200325 fault_handler_t *handler = NULL;
Victor Stinnerc9256172011-05-07 12:20:11 +0200326 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200327
328 if (!fatal_error.enabled)
329 return;
330
331 for (i=0; i < faulthandler_nsignals; i++) {
332 handler = &faulthandler_handlers[i];
333 if (handler->signum == signum)
334 break;
335 }
336 if (handler == NULL) {
337 /* faulthandler_nsignals == 0 (unlikely) */
338 return;
339 }
340
341 /* restore the previous handler */
Victor Stinner404cdc52016-03-23 10:39:17 +0100342 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200343
344 PUTS(fd, "Fatal Python error: ");
345 PUTS(fd, handler->name);
346 PUTS(fd, "\n\n");
347
Victor Stinnerc7489a52015-04-01 18:48:58 +0200348 faulthandler_dump_traceback(fd, fatal_error.all_threads,
349 fatal_error.interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200350
Victor Stinnerc9256172011-05-07 12:20:11 +0200351 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200352#ifdef MS_WINDOWS
353 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200354 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200355 handler, because the Windows signal handler would not be called */
356 return;
357 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200358#endif
R David Murrayfc069992013-12-13 20:52:19 -0500359 /* call the previous signal handler: it is called immediately if we use
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200360 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
361 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200362}
363
Victor Stinner404cdc52016-03-23 10:39:17 +0100364#ifdef MS_WINDOWS
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700365static int
366faulthandler_ignore_exception(DWORD code)
367{
368 /* bpo-30557: ignore exceptions which are not errors */
369 if (!(code & 0x80000000)) {
370 return 1;
371 }
372 /* bpo-31701: ignore MSC and COM exceptions
373 E0000000 + code */
374 if (code == 0xE06D7363 /* MSC exception ("Emsc") */
375 || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
376 return 1;
377 }
378 /* Interesting exception: log it with the Python traceback */
379 return 0;
380}
381
Victor Stinner404cdc52016-03-23 10:39:17 +0100382static LONG WINAPI
383faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
384{
385 const int fd = fatal_error.fd;
386 DWORD code = exc_info->ExceptionRecord->ExceptionCode;
Victor Stinner412a5e72016-03-23 14:44:14 +0100387 DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
Victor Stinner404cdc52016-03-23 10:39:17 +0100388
Victor Stinner6e3d6b52017-10-09 09:52:32 -0700389 if (faulthandler_ignore_exception(code)) {
390 /* ignore the exception: call the next exception handler */
Victor Stinner412a5e72016-03-23 14:44:14 +0100391 return EXCEPTION_CONTINUE_SEARCH;
392 }
393
394 PUTS(fd, "Windows fatal exception: ");
Victor Stinner404cdc52016-03-23 10:39:17 +0100395 switch (code)
396 {
397 /* only format most common errors */
398 case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
399 case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
400 case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
401 case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
402 case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
403 case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
404 case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
405 default:
Steve Dowere6a23c82017-06-05 15:54:15 -0700406 PUTS(fd, "code 0x");
407 _Py_DumpHexadecimal(fd, code, 8);
Victor Stinner404cdc52016-03-23 10:39:17 +0100408 }
409 PUTS(fd, "\n\n");
410
411 if (code == EXCEPTION_ACCESS_VIOLATION) {
412 /* disable signal handler for SIGSEGV */
Victor Stinner46c2b812017-04-21 18:06:13 +0200413 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner404cdc52016-03-23 10:39:17 +0100414 fault_handler_t *handler = &faulthandler_handlers[i];
415 if (handler->signum == SIGSEGV) {
416 faulthandler_disable_fatal_handler(handler);
417 break;
418 }
419 }
420 }
421
422 faulthandler_dump_traceback(fd, fatal_error.all_threads,
423 fatal_error.interp);
424
425 /* call the next exception handler */
426 return EXCEPTION_CONTINUE_SEARCH;
427}
428#endif
429
Victor Stinnerd727e232011-04-01 12:13:55 +0200430/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200431
doko@ubuntu.combc731502016-05-18 01:06:01 +0200432static int
Victor Stinner404cdc52016-03-23 10:39:17 +0100433faulthandler_enable(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200434{
Victor Stinner404cdc52016-03-23 10:39:17 +0100435 if (fatal_error.enabled) {
436 return 0;
437 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100438 fatal_error.enabled = 1;
439
Victor Stinner46c2b812017-04-21 18:06:13 +0200440 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner928ad282016-03-23 15:19:12 +0100441 fault_handler_t *handler;
442#ifdef HAVE_SIGACTION
443 struct sigaction action;
444#endif
445 int err;
Victor Stinner404cdc52016-03-23 10:39:17 +0100446
Victor Stinner928ad282016-03-23 15:19:12 +0100447 handler = &faulthandler_handlers[i];
448 assert(!handler->enabled);
Victor Stinner404cdc52016-03-23 10:39:17 +0100449#ifdef HAVE_SIGACTION
450 action.sa_handler = faulthandler_fatal_error;
451 sigemptyset(&action.sa_mask);
452 /* Do not prevent the signal from being received from within
453 its own signal handler */
454 action.sa_flags = SA_NODEFER;
455#ifdef HAVE_SIGALTSTACK
456 if (stack.ss_sp != NULL) {
457 /* Call the signal handler on an alternate signal stack
458 provided by sigaltstack() */
459 action.sa_flags |= SA_ONSTACK;
460 }
461#endif
462 err = sigaction(handler->signum, &action, &handler->previous);
463#else
464 handler->previous = signal(handler->signum,
465 faulthandler_fatal_error);
466 err = (handler->previous == SIG_ERR);
467#endif
468 if (err) {
469 PyErr_SetFromErrno(PyExc_RuntimeError);
470 return -1;
471 }
472
473 handler->enabled = 1;
474 }
475
476#ifdef MS_WINDOWS
Victor Stinner46c2b812017-04-21 18:06:13 +0200477 assert(fatal_error.exc_handler == NULL);
478 fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler);
Victor Stinner404cdc52016-03-23 10:39:17 +0100479#endif
480 return 0;
481}
482
483static PyObject*
484faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
485{
486 static char *kwlist[] = {"file", "all_threads", NULL};
487 PyObject *file = NULL;
488 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200489 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200490 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200491
492 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
493 "|Oi:enable", kwlist, &file, &all_threads))
494 return NULL;
495
Victor Stinner95bb7142015-03-12 15:32:03 +0100496 fd = faulthandler_get_fileno(&file);
497 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200498 return NULL;
499
Victor Stinnera4de6d82011-04-09 00:47:23 +0200500 tstate = get_thread_state();
501 if (tstate == NULL)
502 return NULL;
503
Victor Stinner95bb7142015-03-12 15:32:03 +0100504 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300505 Py_XSETREF(fatal_error.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200506 fatal_error.fd = fd;
507 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200508 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200509
Victor Stinner404cdc52016-03-23 10:39:17 +0100510 if (faulthandler_enable() < 0) {
511 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200512 }
Victor Stinner404cdc52016-03-23 10:39:17 +0100513
Victor Stinner024e37a2011-03-31 01:31:06 +0200514 Py_RETURN_NONE;
515}
516
517static void
518faulthandler_disable(void)
519{
Victor Stinner024e37a2011-03-31 01:31:06 +0200520 if (fatal_error.enabled) {
521 fatal_error.enabled = 0;
Victor Stinner46c2b812017-04-21 18:06:13 +0200522 for (size_t i=0; i < faulthandler_nsignals; i++) {
523 fault_handler_t *handler;
Victor Stinner024e37a2011-03-31 01:31:06 +0200524 handler = &faulthandler_handlers[i];
Victor Stinner404cdc52016-03-23 10:39:17 +0100525 faulthandler_disable_fatal_handler(handler);
Victor Stinner024e37a2011-03-31 01:31:06 +0200526 }
527 }
Victor Stinner46c2b812017-04-21 18:06:13 +0200528#ifdef MS_WINDOWS
529 if (fatal_error.exc_handler != NULL) {
530 RemoveVectoredExceptionHandler(fatal_error.exc_handler);
531 fatal_error.exc_handler = NULL;
532 }
533#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200534 Py_CLEAR(fatal_error.file);
535}
536
537static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530538faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200539{
540 if (!fatal_error.enabled) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200541 Py_RETURN_FALSE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200542 }
543 faulthandler_disable();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200544 Py_RETURN_TRUE;
Victor Stinner024e37a2011-03-31 01:31:06 +0200545}
546
547static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530548faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200549{
550 return PyBool_FromLong(fatal_error.enabled);
551}
552
553#ifdef FAULTHANDLER_LATER
554
555static void
556faulthandler_thread(void *unused)
557{
558 PyLockStatus st;
559 const char* errmsg;
Victor Stinner024e37a2011-03-31 01:31:06 +0200560 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200561#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200562 sigset_t set;
563
564 /* we don't want to receive any signal */
565 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200566 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200567#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200568
569 do {
570 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200571 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200572 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200573 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200574 break;
575 }
576 /* Timeout => dump traceback */
577 assert(st == PY_LOCK_FAILURE);
578
Victor Stinnerc7489a52015-04-01 18:48:58 +0200579 _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200580
Victor Stinner861d9ab2016-03-16 22:45:24 +0100581 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200582 ok = (errmsg == NULL);
583
584 if (thread.exit)
585 _exit(1);
586 } while (ok && thread.repeat);
587
588 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200589 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200590}
591
592static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200593cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200594{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200595 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200596 PyThread_release_lock(thread.cancel_event);
597
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200598 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200599 PyThread_acquire_lock(thread.running, 1);
600 PyThread_release_lock(thread.running);
601
602 /* The main thread should always hold the cancel_event lock */
603 PyThread_acquire_lock(thread.cancel_event, 1);
604
Victor Stinner024e37a2011-03-31 01:31:06 +0200605 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200606 if (thread.header) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200607 PyMem_Free(thread.header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200608 thread.header = NULL;
609 }
610}
611
Victor Stinner93fd4782017-10-27 07:27:12 -0700612#define SEC_TO_US (1000 * 1000)
613
Victor Stinnerc790a532011-04-08 13:39:59 +0200614static char*
Victor Stinner93fd4782017-10-27 07:27:12 -0700615format_timeout(_PyTime_t us)
Victor Stinnerc790a532011-04-08 13:39:59 +0200616{
Victor Stinner93fd4782017-10-27 07:27:12 -0700617 unsigned long sec, min, hour;
Victor Stinnerc790a532011-04-08 13:39:59 +0200618 char buffer[100];
619
Victor Stinner93fd4782017-10-27 07:27:12 -0700620 /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */
621 sec = (unsigned long)(us / SEC_TO_US);
622 us %= SEC_TO_US;
623
Victor Stinnerc790a532011-04-08 13:39:59 +0200624 min = sec / 60;
625 sec %= 60;
626 hour = min / 60;
627 min %= 60;
628
Victor Stinner93fd4782017-10-27 07:27:12 -0700629 if (us != 0) {
Victor Stinnerc790a532011-04-08 13:39:59 +0200630 PyOS_snprintf(buffer, sizeof(buffer),
Victor Stinner93fd4782017-10-27 07:27:12 -0700631 "Timeout (%lu:%02lu:%02lu.%06u)!\n",
632 hour, min, sec, (unsigned int)us);
633 }
634 else {
Victor Stinnerc790a532011-04-08 13:39:59 +0200635 PyOS_snprintf(buffer, sizeof(buffer),
636 "Timeout (%lu:%02lu:%02lu)!\n",
637 hour, min, sec);
Victor Stinner93fd4782017-10-27 07:27:12 -0700638 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200639 return _PyMem_Strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200640}
641
642static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200643faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200644 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200645{
646 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
Victor Stinner93fd4782017-10-27 07:27:12 -0700647 PyObject *timeout_obj;
648 _PyTime_t timeout, timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200649 int repeat = 0;
650 PyObject *file = NULL;
651 int fd;
652 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200653 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200654 char *header;
655 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200656
657 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinner93fd4782017-10-27 07:27:12 -0700658 "O|iOi:dump_traceback_later", kwlist,
659 &timeout_obj, &repeat, &file, &exit))
Victor Stinner024e37a2011-03-31 01:31:06 +0200660 return NULL;
Victor Stinner93fd4782017-10-27 07:27:12 -0700661
662 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
663 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200664 return NULL;
665 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700666 timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner94189322011-04-08 13:00:31 +0200667 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200668 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
669 return NULL;
670 }
Victor Stinner93fd4782017-10-27 07:27:12 -0700671 /* Limit to LONG_MAX seconds for format_timeout() */
672 if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) {
673 PyErr_SetString(PyExc_OverflowError,
674 "timeout value is too large");
675 return NULL;
676 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200677
Victor Stinnera4de6d82011-04-09 00:47:23 +0200678 tstate = get_thread_state();
679 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200680 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200681
Victor Stinner95bb7142015-03-12 15:32:03 +0100682 fd = faulthandler_get_fileno(&file);
683 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200684 return NULL;
685
Victor Stinnerc790a532011-04-08 13:39:59 +0200686 /* format the timeout */
Victor Stinner93fd4782017-10-27 07:27:12 -0700687 header = format_timeout(timeout_us);
Victor Stinnerc790a532011-04-08 13:39:59 +0200688 if (header == NULL)
689 return PyErr_NoMemory();
690 header_len = strlen(header);
691
Victor Stinner024e37a2011-03-31 01:31:06 +0200692 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200693 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200694
Victor Stinner95bb7142015-03-12 15:32:03 +0100695 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300696 Py_XSETREF(thread.file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200697 thread.fd = fd;
Victor Stinner93fd4782017-10-27 07:27:12 -0700698 /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
699 thread.timeout_us = (PY_TIMEOUT_T)timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200700 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200701 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200702 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200703 thread.header = header;
704 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200705
706 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200707 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200708
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200709 if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200710 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200711 Py_CLEAR(thread.file);
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200712 PyMem_Free(header);
Victor Stinnerc790a532011-04-08 13:39:59 +0200713 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200714 PyErr_SetString(PyExc_RuntimeError,
715 "unable to start watchdog thread");
716 return NULL;
717 }
718
719 Py_RETURN_NONE;
720}
721
722static PyObject*
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530723faulthandler_cancel_dump_traceback_later_py(PyObject *self,
724 PyObject *Py_UNUSED(ignored))
Victor Stinner024e37a2011-03-31 01:31:06 +0200725{
Georg Brandldeb92b52012-09-22 08:58:55 +0200726 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200727 Py_RETURN_NONE;
728}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200729#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200730
731#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200732static int
733faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
734{
735#ifdef HAVE_SIGACTION
736 struct sigaction action;
737 action.sa_handler = faulthandler_user;
738 sigemptyset(&action.sa_mask);
739 /* if the signal is received while the kernel is executing a system
740 call, try to restart the system call instead of interrupting it and
741 return EINTR. */
742 action.sa_flags = SA_RESTART;
743 if (chain) {
744 /* do not prevent the signal from being received from within its
745 own signal handler */
746 action.sa_flags = SA_NODEFER;
747 }
748#ifdef HAVE_SIGALTSTACK
749 if (stack.ss_sp != NULL) {
750 /* Call the signal handler on an alternate signal stack
751 provided by sigaltstack() */
752 action.sa_flags |= SA_ONSTACK;
753 }
754#endif
755 return sigaction(signum, &action, p_previous);
756#else
757 _Py_sighandler_t previous;
758 previous = signal(signum, faulthandler_user);
759 if (p_previous != NULL)
760 *p_previous = previous;
761 return (previous == SIG_ERR);
762#endif
763}
764
Victor Stinner024e37a2011-03-31 01:31:06 +0200765/* Handler of user signals (e.g. SIGUSR1).
766
767 Dump the traceback of the current thread, or of all threads if
768 thread.all_threads is true.
769
770 This function is signal safe and should only call signal safe functions. */
771
772static void
773faulthandler_user(int signum)
774{
775 user_signal_t *user;
Victor Stinnerc9256172011-05-07 12:20:11 +0200776 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200777
778 user = &user_signals[signum];
779 if (!user->enabled)
780 return;
781
Victor Stinnerc7489a52015-04-01 18:48:58 +0200782 faulthandler_dump_traceback(user->fd, user->all_threads, user->interp);
Victor Stinner024e37a2011-03-31 01:31:06 +0200783
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200784#ifdef HAVE_SIGACTION
785 if (user->chain) {
786 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200787 errno = save_errno;
788
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200789 /* call the previous signal handler */
790 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200791
792 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200793 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200794 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200795 }
796#else
797 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200798 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200799 /* call the previous signal handler */
800 user->previous(signum);
801 }
802#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200803}
804
805static int
806check_signum(int signum)
807{
Victor Stinner46c2b812017-04-21 18:06:13 +0200808 for (size_t i=0; i < faulthandler_nsignals; i++) {
Victor Stinner44378d42011-04-01 15:37:12 +0200809 if (faulthandler_handlers[i].signum == signum) {
810 PyErr_Format(PyExc_RuntimeError,
811 "signal %i cannot be registered, "
812 "use enable() instead",
813 signum);
814 return 0;
815 }
816 }
817 if (signum < 1 || NSIG <= signum) {
818 PyErr_SetString(PyExc_ValueError, "signal number out of range");
819 return 0;
820 }
821 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200822}
823
824static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200825faulthandler_register_py(PyObject *self,
826 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200827{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200828 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200829 int signum;
830 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200831 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200832 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200833 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200834 user_signal_t *user;
835 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200836 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200837 int err;
838
839 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200840 "i|Oii:register", kwlist,
841 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200842 return NULL;
843
Victor Stinner44378d42011-04-01 15:37:12 +0200844 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200845 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200846
Victor Stinnera4de6d82011-04-09 00:47:23 +0200847 tstate = get_thread_state();
848 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200849 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200850
Victor Stinner95bb7142015-03-12 15:32:03 +0100851 fd = faulthandler_get_fileno(&file);
852 if (fd < 0)
Victor Stinner024e37a2011-03-31 01:31:06 +0200853 return NULL;
854
855 if (user_signals == NULL) {
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200856 user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200857 if (user_signals == NULL)
858 return PyErr_NoMemory();
Victor Stinner49fc8ec2013-07-07 23:30:24 +0200859 memset(user_signals, 0, NSIG * sizeof(user_signal_t));
Victor Stinner024e37a2011-03-31 01:31:06 +0200860 }
861 user = &user_signals[signum];
862
863 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200864 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200865 if (err) {
866 PyErr_SetFromErrno(PyExc_OSError);
867 return NULL;
868 }
Victor Stinner8d379542013-07-02 00:14:56 +0200869
870 user->previous = previous;
Victor Stinner024e37a2011-03-31 01:31:06 +0200871 }
872
Victor Stinner95bb7142015-03-12 15:32:03 +0100873 Py_XINCREF(file);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300874 Py_XSETREF(user->file, file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200875 user->fd = fd;
876 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200877 user->chain = chain;
Victor Stinner44378d42011-04-01 15:37:12 +0200878 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200879 user->enabled = 1;
880
881 Py_RETURN_NONE;
882}
883
884static int
885faulthandler_unregister(user_signal_t *user, int signum)
886{
Victor Stinnera01ca122011-04-01 12:56:17 +0200887 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200888 return 0;
889 user->enabled = 0;
890#ifdef HAVE_SIGACTION
891 (void)sigaction(signum, &user->previous, NULL);
892#else
893 (void)signal(signum, user->previous);
894#endif
895 Py_CLEAR(user->file);
896 user->fd = -1;
897 return 1;
898}
899
900static PyObject*
901faulthandler_unregister_py(PyObject *self, PyObject *args)
902{
903 int signum;
904 user_signal_t *user;
905 int change;
906
907 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
908 return NULL;
909
Victor Stinner44378d42011-04-01 15:37:12 +0200910 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200911 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200912
Victor Stinnercfa71232011-04-08 12:48:15 +0200913 if (user_signals == NULL)
914 Py_RETURN_FALSE;
915
Victor Stinner024e37a2011-03-31 01:31:06 +0200916 user = &user_signals[signum];
917 change = faulthandler_unregister(user, signum);
918 return PyBool_FromLong(change);
919}
920#endif /* FAULTHANDLER_USER */
921
922
Victor Stinner7a399122014-09-30 13:40:12 +0200923static void
924faulthandler_suppress_crash_report(void)
925{
926#ifdef MS_WINDOWS
927 UINT mode;
928
929 /* Configure Windows to not display the Windows Error Reporting dialog */
930 mode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
931 SetErrorMode(mode | SEM_NOGPFAULTERRORBOX);
932#endif
933
934#ifdef HAVE_SYS_RESOURCE_H
935 struct rlimit rl;
936
937 /* Disable creation of core dump */
Victor Stinner48d4dd92017-12-11 13:57:12 +0100938 if (getrlimit(RLIMIT_CORE, &rl) == 0) {
Victor Stinner7a399122014-09-30 13:40:12 +0200939 rl.rlim_cur = 0;
940 setrlimit(RLIMIT_CORE, &rl);
941 }
942#endif
943
944#ifdef _MSC_VER
945 /* Visual Studio: configure abort() to not display an error message nor
946 open a popup asking to report the fault. */
947 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
948#endif
949}
950
Victor Stinner024e37a2011-03-31 01:31:06 +0200951static PyObject *
952faulthandler_read_null(PyObject *self, PyObject *args)
953{
Victor Stinnera2477202012-01-30 00:07:43 +0100954 volatile int *x;
955 volatile int y;
Victor Stinnera2477202012-01-30 00:07:43 +0100956
Victor Stinner7a399122014-09-30 13:40:12 +0200957 faulthandler_suppress_crash_report();
Victor Stinnera2477202012-01-30 00:07:43 +0100958 x = NULL;
Victor Stinner50838282014-09-30 13:54:14 +0200959 y = *x;
Victor Stinner024e37a2011-03-31 01:31:06 +0200960 return PyLong_FromLong(y);
961
962}
963
Victor Stinner50838282014-09-30 13:54:14 +0200964static void
965faulthandler_raise_sigsegv(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200966{
Victor Stinner7a399122014-09-30 13:40:12 +0200967 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +0200968#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200969 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
970 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200971 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200972 SIGSEGV was raised by the kernel because of a fault, and so if the
973 program retries to execute the same instruction, the fault will be
974 raised again.
975
976 Here the fault is simulated by a fake SIGSEGV signal raised by the
977 application. We have to raise SIGSEGV at lease twice: once for
978 faulthandler_fatal_error(), and one more time for the previous signal
979 handler. */
980 while(1)
981 raise(SIGSEGV);
982#else
983 raise(SIGSEGV);
984#endif
Victor Stinner50838282014-09-30 13:54:14 +0200985}
986
987static PyObject *
988faulthandler_sigsegv(PyObject *self, PyObject *args)
989{
990 int release_gil = 0;
Victor Stinner861d9ab2016-03-16 22:45:24 +0100991 if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
Victor Stinner50838282014-09-30 13:54:14 +0200992 return NULL;
993
994 if (release_gil) {
995 Py_BEGIN_ALLOW_THREADS
996 faulthandler_raise_sigsegv();
997 Py_END_ALLOW_THREADS
998 } else {
999 faulthandler_raise_sigsegv();
1000 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001001 Py_RETURN_NONE;
1002}
1003
Victor Stinner861d9ab2016-03-16 22:45:24 +01001004static void
1005faulthandler_fatal_error_thread(void *plock)
1006{
Victor Stinner9a2329f2016-12-05 17:56:36 +01001007#ifndef __clang__
Victor Stinner861d9ab2016-03-16 22:45:24 +01001008 PyThread_type_lock *lock = (PyThread_type_lock *)plock;
Victor Stinner9a2329f2016-12-05 17:56:36 +01001009#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001010
1011 Py_FatalError("in new thread");
1012
Victor Stinner9a2329f2016-12-05 17:56:36 +01001013#ifndef __clang__
1014 /* Issue #28152: Py_FatalError() is declared with
1015 __attribute__((__noreturn__)). GCC emits a warning without
1016 "PyThread_release_lock()" (compiler bug?), but Clang is smarter and
1017 emits a warning on the return. */
1018
Victor Stinner861d9ab2016-03-16 22:45:24 +01001019 /* notify the caller that we are done */
1020 PyThread_release_lock(lock);
Victor Stinner9a2329f2016-12-05 17:56:36 +01001021#endif
Victor Stinner861d9ab2016-03-16 22:45:24 +01001022}
1023
1024static PyObject *
1025faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
1026{
1027 long thread;
1028 PyThread_type_lock lock;
1029
1030 faulthandler_suppress_crash_report();
1031
1032 lock = PyThread_allocate_lock();
1033 if (lock == NULL)
1034 return PyErr_NoMemory();
1035
1036 PyThread_acquire_lock(lock, WAIT_LOCK);
1037
1038 thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
1039 if (thread == -1) {
1040 PyThread_free_lock(lock);
1041 PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
1042 return NULL;
1043 }
1044
1045 /* wait until the thread completes: it will never occur, since Py_FatalError()
Mike53f7a7c2017-12-14 14:04:53 +03001046 exits the process immediately. */
Victor Stinner861d9ab2016-03-16 22:45:24 +01001047 PyThread_acquire_lock(lock, WAIT_LOCK);
1048 PyThread_release_lock(lock);
1049 PyThread_free_lock(lock);
1050
1051 Py_RETURN_NONE;
1052}
Victor Stinner861d9ab2016-03-16 22:45:24 +01001053
Victor Stinner024e37a2011-03-31 01:31:06 +02001054static PyObject *
1055faulthandler_sigfpe(PyObject *self, PyObject *args)
1056{
1057 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
1058 PowerPC. Use volatile to disable compile-time optimizations. */
1059 volatile int x = 1, y = 0, z;
Victor Stinner7a399122014-09-30 13:40:12 +02001060 faulthandler_suppress_crash_report();
Victor Stinner024e37a2011-03-31 01:31:06 +02001061 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +02001062 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
1063 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001064 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +02001065 /* This line is never reached, but we pretend to make something with z
1066 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +02001067 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +02001068}
1069
Victor Stinnerd727e232011-04-01 12:13:55 +02001070static PyObject *
1071faulthandler_sigabrt(PyObject *self, PyObject *args)
1072{
Victor Stinner7a399122014-09-30 13:40:12 +02001073 faulthandler_suppress_crash_report();
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001074 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001075 Py_RETURN_NONE;
1076}
1077
Victor Stinner024e37a2011-03-31 01:31:06 +02001078static PyObject *
1079faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1080{
1081 char *message;
Victor Stinner57003f82016-03-15 17:23:35 +01001082 int release_gil = 0;
1083 if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
Victor Stinner024e37a2011-03-31 01:31:06 +02001084 return NULL;
Victor Stinner7a399122014-09-30 13:40:12 +02001085 faulthandler_suppress_crash_report();
Victor Stinner57003f82016-03-15 17:23:35 +01001086 if (release_gil) {
1087 Py_BEGIN_ALLOW_THREADS
1088 Py_FatalError(message);
1089 Py_END_ALLOW_THREADS
1090 }
1091 else {
1092 Py_FatalError(message);
1093 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001094 Py_RETURN_NONE;
1095}
1096
1097#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner404cdc52016-03-23 10:39:17 +01001098#define FAULTHANDLER_STACK_OVERFLOW
1099
Victor Stinner19276f12015-03-23 21:20:27 +01001100#ifdef __INTEL_COMPILER
1101 /* Issue #23654: Turn off ICC's tail call optimization for the
1102 * stack_overflow generator. ICC turns the recursive tail call into
1103 * a loop. */
1104# pragma intel optimization_level 0
1105#endif
1106static
Benjamin Petersonca470632016-09-06 13:47:26 -07001107uintptr_t
1108stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001109{
1110 /* allocate 4096 bytes on the stack at each call */
1111 unsigned char buffer[4096];
Benjamin Petersonca470632016-09-06 13:47:26 -07001112 uintptr_t sp = (uintptr_t)&buffer;
Victor Stinnerf0480752011-03-31 11:34:08 +02001113 *depth += 1;
Victor Stinner928ad282016-03-23 15:19:12 +01001114 if (sp < min_sp || max_sp < sp)
Victor Stinnerf0480752011-03-31 11:34:08 +02001115 return sp;
Victor Stinner928ad282016-03-23 15:19:12 +01001116 buffer[0] = 1;
1117 buffer[4095] = 0;
1118 return stack_overflow(min_sp, max_sp, depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001119}
1120
1121static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301122faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
Victor Stinnerf0480752011-03-31 11:34:08 +02001123{
1124 size_t depth, size;
Benjamin Petersonca470632016-09-06 13:47:26 -07001125 uintptr_t sp = (uintptr_t)&depth;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001126 uintptr_t stop, lower_limit, upper_limit;
Victor Stinnerf0480752011-03-31 11:34:08 +02001127
Victor Stinner7a399122014-09-30 13:40:12 +02001128 faulthandler_suppress_crash_report();
Victor Stinnerf0480752011-03-31 11:34:08 +02001129 depth = 0;
Xi Ruoyao6236c982019-05-12 01:13:23 +08001130
1131 if (STACK_OVERFLOW_MAX_SIZE <= sp) {
1132 lower_limit = sp - STACK_OVERFLOW_MAX_SIZE;
1133 }
1134 else {
1135 lower_limit = 0;
1136 }
1137
1138 if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) {
1139 upper_limit = sp + STACK_OVERFLOW_MAX_SIZE;
1140 }
1141 else {
1142 upper_limit = UINTPTR_MAX;
1143 }
1144
1145 stop = stack_overflow(lower_limit, upper_limit, &depth);
Victor Stinnerf0480752011-03-31 11:34:08 +02001146 if (sp < stop)
1147 size = stop - sp;
1148 else
1149 size = sp - stop;
1150 PyErr_Format(PyExc_RuntimeError,
1151 "unable to raise a stack overflow (allocated %zu bytes "
1152 "on the stack, %zu recursive calls)",
1153 size, depth);
1154 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001155}
Victor Stinner928ad282016-03-23 15:19:12 +01001156#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */
Victor Stinner024e37a2011-03-31 01:31:06 +02001157
1158
1159static int
1160faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1161{
Victor Stinner024e37a2011-03-31 01:31:06 +02001162#ifdef FAULTHANDLER_LATER
1163 Py_VISIT(thread.file);
1164#endif
1165#ifdef FAULTHANDLER_USER
1166 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001167 for (size_t signum=0; signum < NSIG; signum++)
Victor Stinner96994402011-04-07 11:37:19 +02001168 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001169 }
1170#endif
1171 Py_VISIT(fatal_error.file);
1172 return 0;
1173}
1174
Victor Stinner404cdc52016-03-23 10:39:17 +01001175#ifdef MS_WINDOWS
1176static PyObject *
1177faulthandler_raise_exception(PyObject *self, PyObject *args)
1178{
1179 unsigned int code, flags = 0;
1180 if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
1181 return NULL;
1182 faulthandler_suppress_crash_report();
1183 RaiseException(code, flags, 0, NULL);
1184 Py_RETURN_NONE;
1185}
1186#endif
1187
Victor Stinner024e37a2011-03-31 01:31:06 +02001188PyDoc_STRVAR(module_doc,
1189"faulthandler module.");
1190
1191static PyMethodDef module_methods[] = {
1192 {"enable",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001193 (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001194 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001195 "enable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301196 {"disable", faulthandler_disable_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001197 PyDoc_STR("disable(): disable the fault handler")},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301198 {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001199 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1200 {"dump_traceback",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001201 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001202 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001203 "dump the traceback of the current thread, or of all threads "
1204 "if all_threads is True, into file")},
1205#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +02001206 {"dump_traceback_later",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001207 (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001208 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001209 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001210 "or each timeout seconds if repeat is True. If exit is True, "
1211 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +02001212 {"cancel_dump_traceback_later",
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301213 faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
Georg Brandldeb92b52012-09-22 08:58:55 +02001214 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
1215 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001216#endif
1217
1218#ifdef FAULTHANDLER_USER
1219 {"register",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001220 (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001221 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03001222 "register a handler for the signal 'signum': dump the "
Victor Stinner024e37a2011-03-31 01:31:06 +02001223 "traceback of the current thread, or of all threads if "
1224 "all_threads is True, into file")},
1225 {"unregister",
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001226 (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001227 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1228 "'signum' registered by register()")},
1229#endif
1230
Victor Stinner50838282014-09-30 13:54:14 +02001231 {"_read_null", faulthandler_read_null, METH_NOARGS,
1232 PyDoc_STR("_read_null(): read from NULL, raise "
Victor Stinner024e37a2011-03-31 01:31:06 +02001233 "a SIGSEGV or SIGBUS signal depending on the platform")},
1234 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
Victor Stinner50838282014-09-30 13:54:14 +02001235 PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")},
Victor Stinner861d9ab2016-03-16 22:45:24 +01001236 {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
1237 PyDoc_STR("fatal_error_c_thread(): "
1238 "call Py_FatalError() in a new C thread.")},
Victor Stinner9db521c2014-09-30 13:49:09 +02001239 {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
Victor Stinnerd727e232011-04-01 12:13:55 +02001240 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001241 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1242 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001243 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1244 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
Victor Stinner404cdc52016-03-23 10:39:17 +01001245#ifdef FAULTHANDLER_STACK_OVERFLOW
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301246 {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001247 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1248#endif
Victor Stinner404cdc52016-03-23 10:39:17 +01001249#ifdef MS_WINDOWS
1250 {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
1251 PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")},
1252#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001253 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001254};
1255
1256static struct PyModuleDef module_def = {
1257 PyModuleDef_HEAD_INIT,
1258 "faulthandler",
1259 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001260 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001261 module_methods,
1262 NULL,
1263 faulthandler_traverse,
1264 NULL,
1265 NULL
1266};
1267
1268PyMODINIT_FUNC
1269PyInit_faulthandler(void)
1270{
Victor Stinner404cdc52016-03-23 10:39:17 +01001271 PyObject *m = PyModule_Create(&module_def);
1272 if (m == NULL)
1273 return NULL;
1274
1275 /* Add constants for unit tests */
1276#ifdef MS_WINDOWS
1277 /* RaiseException() codes (prefixed by an underscore) */
1278 if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION",
1279 EXCEPTION_ACCESS_VIOLATION))
1280 return NULL;
1281 if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
1282 EXCEPTION_INT_DIVIDE_BY_ZERO))
1283 return NULL;
1284 if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW",
1285 EXCEPTION_STACK_OVERFLOW))
1286 return NULL;
1287
1288 /* RaiseException() flags (prefixed by an underscore) */
1289 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE",
1290 EXCEPTION_NONCONTINUABLE))
1291 return NULL;
1292 if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
1293 EXCEPTION_NONCONTINUABLE_EXCEPTION))
1294 return NULL;
1295#endif
1296
1297 return m;
Victor Stinner024e37a2011-03-31 01:31:06 +02001298}
1299
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001300static int
1301faulthandler_init_enable(void)
1302{
1303 PyObject *module = PyImport_ImportModule("faulthandler");
1304 if (module == NULL) {
1305 return -1;
1306 }
1307
1308 PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
1309 Py_DECREF(module);
1310 if (res == NULL) {
1311 return -1;
1312 }
1313 Py_DECREF(res);
1314
1315 return 0;
1316}
1317
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001318_PyInitError
Victor Stinnera7368ac2017-11-15 18:11:45 -08001319_PyFaulthandler_Init(int enable)
Victor Stinner024e37a2011-03-31 01:31:06 +02001320{
1321#ifdef HAVE_SIGALTSTACK
1322 int err;
1323
1324 /* Try to allocate an alternate stack for faulthandler() signal handler to
1325 * be able to allocate memory on the stack, even on a stack overflow. If it
1326 * fails, ignore the error. */
1327 stack.ss_flags = 0;
1328 stack.ss_size = SIGSTKSZ;
1329 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1330 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001331 err = sigaltstack(&stack, &old_stack);
Victor Stinner024e37a2011-03-31 01:31:06 +02001332 if (err) {
1333 PyMem_Free(stack.ss_sp);
1334 stack.ss_sp = NULL;
1335 }
1336 }
1337#endif
1338#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001339 thread.file = NULL;
1340 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001341 thread.running = PyThread_allocate_lock();
1342 if (!thread.cancel_event || !thread.running) {
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001343 return _Py_INIT_ERR("failed to allocate locks for faulthandler");
Victor Stinner024e37a2011-03-31 01:31:06 +02001344 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001345 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001346#endif
1347
Victor Stinnerf7e5b562017-11-15 15:48:08 -08001348 if (enable) {
1349 if (faulthandler_init_enable() < 0) {
1350 return _Py_INIT_ERR("failed to enable faulthandler");
1351 }
1352 }
1353 return _Py_INIT_OK();
Victor Stinner024e37a2011-03-31 01:31:06 +02001354}
1355
1356void _PyFaulthandler_Fini(void)
1357{
Victor Stinner024e37a2011-03-31 01:31:06 +02001358#ifdef FAULTHANDLER_LATER
1359 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001360 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001361 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001362 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001363 PyThread_free_lock(thread.cancel_event);
1364 thread.cancel_event = NULL;
1365 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001366 if (thread.running) {
1367 PyThread_free_lock(thread.running);
1368 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001369 }
1370#endif
1371
1372#ifdef FAULTHANDLER_USER
1373 /* user */
1374 if (user_signals != NULL) {
Victor Stinner46c2b812017-04-21 18:06:13 +02001375 for (size_t signum=0; signum < NSIG; signum++) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001376 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner46c2b812017-04-21 18:06:13 +02001377 }
Victor Stinner49fc8ec2013-07-07 23:30:24 +02001378 PyMem_Free(user_signals);
Victor Stinner024e37a2011-03-31 01:31:06 +02001379 user_signals = NULL;
1380 }
1381#endif
1382
1383 /* fatal */
1384 faulthandler_disable();
1385#ifdef HAVE_SIGALTSTACK
1386 if (stack.ss_sp != NULL) {
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001387 /* Fetch the current alt stack */
Victor Stinnerb84cb702019-04-30 12:19:34 +02001388 stack_t current_stack;
1389 memset(&current_stack, 0, sizeof(current_stack));
Christophe Zeitouny20fbf8a2017-03-23 10:14:29 -07001390 if (sigaltstack(NULL, &current_stack) == 0) {
1391 if (current_stack.ss_sp == stack.ss_sp) {
1392 /* The current alt stack is the one that we installed.
1393 It is safe to restore the old stack that we found when
1394 we installed ours */
1395 sigaltstack(&old_stack, NULL);
1396 } else {
1397 /* Someone switched to a different alt stack and didn't
1398 restore ours when they were done (if they're done).
1399 There's not much we can do in this unlikely case */
1400 }
1401 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001402 PyMem_Free(stack.ss_sp);
1403 stack.ss_sp = NULL;
1404 }
1405#endif
1406}