blob: abc12a0ff8e4869dd13112aa78890cba5b16b577 [file] [log] [blame]
Victor Stinner024e37a2011-03-31 01:31:06 +02001#include "Python.h"
2#include "pythread.h"
3#include <signal.h>
4#include <object.h>
5#include <frameobject.h>
6#include <signal.h>
7
8#ifdef WITH_THREAD
9# define FAULTHANDLER_LATER
10#endif
11
12#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020013 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
14 SIGILL can be handled by the process, and these signals can only be used
15 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020016# define FAULTHANDLER_USER
17#endif
18
Victor Stinnerf0480752011-03-31 11:34:08 +020019/* Allocate at maximum 100 MB of the stack to raise the stack overflow */
20#define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
21
Victor Stinner024e37a2011-03-31 01:31:06 +020022#define PUTS(fd, str) write(fd, str, strlen(str))
23
24#ifdef HAVE_SIGACTION
25typedef struct sigaction _Py_sighandler_t;
26#else
27typedef PyOS_sighandler_t _Py_sighandler_t;
28#endif
29
30typedef struct {
31 int signum;
32 int enabled;
33 const char* name;
34 _Py_sighandler_t previous;
35 int all_threads;
36} fault_handler_t;
37
38static struct {
39 int enabled;
40 PyObject *file;
41 int fd;
42 int all_threads;
43} fatal_error = {0, NULL, -1, 0};
44
45#ifdef FAULTHANDLER_LATER
46static struct {
47 PyObject *file;
48 int fd;
49 PY_TIMEOUT_T timeout_ms; /* timeout in microseconds */
50 int repeat;
Victor Stinnerf3091342011-04-01 03:16:51 +020051 int running;
Victor Stinner024e37a2011-03-31 01:31:06 +020052 PyInterpreterState *interp;
53 int exit;
54 /* released by parent thread when cancel request */
55 PyThread_type_lock cancel_event;
56 /* released by child thread when joined */
57 PyThread_type_lock join_event;
58} thread;
59#endif
60
61#ifdef FAULTHANDLER_USER
62typedef struct {
63 int enabled;
64 PyObject *file;
65 int fd;
66 int all_threads;
67 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020068 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020069} user_signal_t;
70
71static user_signal_t *user_signals;
72
73/* the following macros come from Python: Modules/signalmodule.c */
74#if defined(PYOS_OS2) && !defined(PYCC_GCC)
75#define NSIG 12
76#endif
77#ifndef NSIG
78# if defined(_NSIG)
79# define NSIG _NSIG /* For BSD/SysV */
80# elif defined(_SIGMAX)
81# define NSIG (_SIGMAX + 1) /* For QNX */
82# elif defined(SIGMAX)
83# define NSIG (SIGMAX + 1) /* For djgpp */
84# else
85# define NSIG 64 /* Use a reasonable default value */
86# endif
87#endif
88
89#endif /* FAULTHANDLER_USER */
90
91
92static fault_handler_t faulthandler_handlers[] = {
93#ifdef SIGBUS
94 {SIGBUS, 0, "Bus error", },
95#endif
96#ifdef SIGILL
97 {SIGILL, 0, "Illegal instruction", },
98#endif
99 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200100 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200101 /* define SIGSEGV at the end to make it the default choice if searching the
102 handler fails in faulthandler_fatal_error() */
103 {SIGSEGV, 0, "Segmentation fault", }
104};
105static const unsigned char faulthandler_nsignals = \
106 sizeof(faulthandler_handlers) / sizeof(faulthandler_handlers[0]);
107
108#ifdef HAVE_SIGALTSTACK
109static stack_t stack;
110#endif
111
112
113/* Get the file descriptor of a file by calling its fileno() method and then
114 call its flush() method.
115
116 If file is NULL or Py_None, use sys.stderr as the new file.
117
118 On success, return the new file and write the file descriptor into *p_fd.
119 On error, return NULL. */
120
121static PyObject*
122faulthandler_get_fileno(PyObject *file, int *p_fd)
123{
124 PyObject *result;
125 long fd_long;
126 int fd;
127
128 if (file == NULL || file == Py_None) {
129 file = PySys_GetObject("stderr");
130 if (file == NULL) {
131 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
132 return NULL;
133 }
134 }
135
136 result = PyObject_CallMethod(file, "fileno", "");
137 if (result == NULL)
138 return NULL;
139
140 fd = -1;
141 if (PyLong_Check(result)) {
142 fd_long = PyLong_AsLong(result);
143 if (0 <= fd_long && fd_long < INT_MAX)
144 fd = (int)fd_long;
145 }
146 Py_DECREF(result);
147
148 if (fd == -1) {
149 PyErr_SetString(PyExc_RuntimeError,
150 "file.fileno() is not a valid file descriptor");
151 return NULL;
152 }
153
154 result = PyObject_CallMethod(file, "flush", "");
155 if (result != NULL)
156 Py_DECREF(result);
157 else {
158 /* ignore flush() error */
159 PyErr_Clear();
160 }
161 *p_fd = fd;
162 return file;
163}
164
165static PyObject*
166faulthandler_dump_traceback_py(PyObject *self,
167 PyObject *args, PyObject *kwargs)
168{
169 static char *kwlist[] = {"file", "all_threads", NULL};
170 PyObject *file = NULL;
171 int all_threads = 0;
172 PyThreadState *tstate;
173 const char *errmsg;
174 int fd;
175
176 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
177 "|Oi:dump_traceback", kwlist,
178 &file, &all_threads))
179 return NULL;
180
181 file = faulthandler_get_fileno(file, &fd);
182 if (file == NULL)
183 return NULL;
184
185 /* The caller holds the GIL and so PyThreadState_Get() can be used */
186 tstate = PyThreadState_Get();
187 if (tstate == NULL) {
188 PyErr_SetString(PyExc_RuntimeError,
189 "unable to get the current thread state");
190 return NULL;
191 }
192
193 if (all_threads) {
194 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
195 if (errmsg != NULL) {
196 PyErr_SetString(PyExc_RuntimeError, errmsg);
197 return NULL;
198 }
199 }
200 else {
201 _Py_DumpTraceback(fd, tstate);
202 }
203 Py_RETURN_NONE;
204}
205
206
Victor Stinnerd727e232011-04-01 12:13:55 +0200207/* Handler of SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200208
209 Display the current Python traceback, restore the previous handler and call
210 the previous handler.
211
212 On Windows, don't call explictly the previous handler, because Windows
213 signal handler would not be called (for an unknown reason). The execution of
214 the program continues at faulthandler_fatal_error() exit, but the same
215 instruction will raise the same fault (signal), and so the previous handler
216 will be called.
217
218 This function is signal safe and should only call signal safe functions. */
219
220static void
221faulthandler_fatal_error(
222 int signum
223#ifdef HAVE_SIGACTION
224 , siginfo_t *siginfo, void *ucontext
225#endif
226)
227{
228 const int fd = fatal_error.fd;
229 unsigned int i;
230 fault_handler_t *handler = NULL;
231 PyThreadState *tstate;
232
233 if (!fatal_error.enabled)
234 return;
235
236 for (i=0; i < faulthandler_nsignals; i++) {
237 handler = &faulthandler_handlers[i];
238 if (handler->signum == signum)
239 break;
240 }
241 if (handler == NULL) {
242 /* faulthandler_nsignals == 0 (unlikely) */
243 return;
244 }
245
246 /* restore the previous handler */
247#ifdef HAVE_SIGACTION
248 (void)sigaction(handler->signum, &handler->previous, NULL);
249#else
250 (void)signal(handler->signum, handler->previous);
251#endif
252 handler->enabled = 0;
253
254 PUTS(fd, "Fatal Python error: ");
255 PUTS(fd, handler->name);
256 PUTS(fd, "\n\n");
257
Victor Stinnerd727e232011-04-01 12:13:55 +0200258 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
259 so are delivered to the thread that caused the fault. Get the Python
260 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200261
262 PyThreadState_Get() doesn't give the state of the thread that caused the
263 fault if the thread released the GIL, and so this function cannot be
264 used. Read the thread local storage (TLS) instead: call
265 PyGILState_GetThisThreadState(). */
266 tstate = PyGILState_GetThisThreadState();
267 if (tstate == NULL)
268 return;
269
270 if (fatal_error.all_threads)
271 _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
272 else
273 _Py_DumpTraceback(fd, tstate);
274
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200275#ifdef MS_WINDOWS
276 if (signum == SIGSEGV) {
277 /* don't call explictly the previous handler for SIGSEGV in this signal
278 handler, because the Windows signal handler would not be called */
279 return;
280 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200281#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200282 /* call the previous signal handler: it is called immediatly if we use
283 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
284 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200285}
286
Victor Stinnerd727e232011-04-01 12:13:55 +0200287/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200288
289static PyObject*
290faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
291{
292 static char *kwlist[] = {"file", "all_threads", NULL};
293 PyObject *file = NULL;
294 int all_threads = 0;
295 unsigned int i;
296 fault_handler_t *handler;
297#ifdef HAVE_SIGACTION
298 struct sigaction action;
299#endif
300 int err;
301 int fd;
302
303 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
304 "|Oi:enable", kwlist, &file, &all_threads))
305 return NULL;
306
307 file = faulthandler_get_fileno(file, &fd);
308 if (file == NULL)
309 return NULL;
310
311 Py_XDECREF(fatal_error.file);
312 Py_INCREF(file);
313 fatal_error.file = file;
314 fatal_error.fd = fd;
315 fatal_error.all_threads = all_threads;
316
317 if (!fatal_error.enabled) {
318 fatal_error.enabled = 1;
319
320 for (i=0; i < faulthandler_nsignals; i++) {
321 handler = &faulthandler_handlers[i];
322#ifdef HAVE_SIGACTION
323 action.sa_sigaction = faulthandler_fatal_error;
324 sigemptyset(&action.sa_mask);
325 /* Do not prevent the signal from being received from within
326 its own signal handler */
327 action.sa_flags = SA_NODEFER;
328#ifdef HAVE_SIGALTSTACK
329 if (stack.ss_sp != NULL) {
330 /* Call the signal handler on an alternate signal stack
331 provided by sigaltstack() */
332 action.sa_flags |= SA_ONSTACK;
333 }
334#endif
335 err = sigaction(handler->signum, &action, &handler->previous);
336#else
337 handler->previous = signal(handler->signum,
338 faulthandler_fatal_error);
339 err = (handler->previous == SIG_ERR);
340#endif
341 if (err) {
342 PyErr_SetFromErrno(PyExc_RuntimeError);
343 return NULL;
344 }
345 handler->enabled = 1;
346 }
347 }
348 Py_RETURN_NONE;
349}
350
351static void
352faulthandler_disable(void)
353{
354 unsigned int i;
355 fault_handler_t *handler;
356
357 if (fatal_error.enabled) {
358 fatal_error.enabled = 0;
359 for (i=0; i < faulthandler_nsignals; i++) {
360 handler = &faulthandler_handlers[i];
361 if (!handler->enabled)
362 continue;
363#ifdef HAVE_SIGACTION
364 (void)sigaction(handler->signum, &handler->previous, NULL);
365#else
366 (void)signal(handler->signum, handler->previous);
367#endif
368 handler->enabled = 0;
369 }
370 }
371
372 Py_CLEAR(fatal_error.file);
373}
374
375static PyObject*
376faulthandler_disable_py(PyObject *self)
377{
378 if (!fatal_error.enabled) {
379 Py_INCREF(Py_False);
380 return Py_False;
381 }
382 faulthandler_disable();
383 Py_INCREF(Py_True);
384 return Py_True;
385}
386
387static PyObject*
388faulthandler_is_enabled(PyObject *self)
389{
390 return PyBool_FromLong(fatal_error.enabled);
391}
392
393#ifdef FAULTHANDLER_LATER
394
395static void
396faulthandler_thread(void *unused)
397{
398 PyLockStatus st;
399 const char* errmsg;
400 PyThreadState *current;
401 int ok;
Victor Stinnerda9edae2011-04-04 11:05:21 +0200402#ifdef HAVE_PTHREAD_H
403 sigset_t set;
404
405 /* we don't want to receive any signal */
406 sigfillset(&set);
407#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
408 pthread_sigmask(SIG_SETMASK, &set, NULL);
409#else
410 sigprocmask(SIG_SETMASK, &set, NULL);
411#endif
412#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200413
414 do {
415 st = PyThread_acquire_lock_timed(thread.cancel_event,
416 thread.timeout_ms, 0);
417 if (st == PY_LOCK_ACQUIRED) {
418 /* Cancelled by user */
419 break;
420 }
421 /* Timeout => dump traceback */
422 assert(st == PY_LOCK_FAILURE);
423
424 /* get the thread holding the GIL, NULL if no thread hold the GIL */
425 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
426
427 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
428 ok = (errmsg == NULL);
429
430 if (thread.exit)
431 _exit(1);
432 } while (ok && thread.repeat);
433
434 /* The only way out */
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200435 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200436 PyThread_release_lock(thread.join_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200437}
438
439static void
Victor Stinner702624e2011-03-31 03:42:34 +0200440faulthandler_cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200441{
442 if (thread.running) {
443 /* Notify cancellation */
444 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200445 }
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200446 /* Wait for thread to join */
447 PyThread_acquire_lock(thread.join_event, 1);
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200448 PyThread_release_lock(thread.join_event);
Victor Stinnerf3091342011-04-01 03:16:51 +0200449 thread.running = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200450 Py_CLEAR(thread.file);
451}
452
453static PyObject*
454faulthandler_dump_traceback_later(PyObject *self,
455 PyObject *args, PyObject *kwargs)
456{
457 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
458 double timeout;
459 PY_TIMEOUT_T timeout_ms;
460 int repeat = 0;
461 PyObject *file = NULL;
462 int fd;
463 int exit = 0;
464
465 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
466 "d|iOi:dump_tracebacks_later", kwlist,
467 &timeout, &repeat, &file, &exit))
468 return NULL;
469 timeout *= 1e6;
470 if (timeout >= (double) PY_TIMEOUT_MAX) {
471 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
472 return NULL;
473 }
474 timeout_ms = (PY_TIMEOUT_T)timeout;
475 if (timeout_ms <= 0) {
476 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
477 return NULL;
478 }
479
480 file = faulthandler_get_fileno(file, &fd);
481 if (file == NULL)
482 return NULL;
483
484 /* Cancel previous thread, if running */
Victor Stinner702624e2011-03-31 03:42:34 +0200485 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200486
487 Py_XDECREF(thread.file);
488 Py_INCREF(file);
489 thread.file = file;
490 thread.fd = fd;
491 thread.timeout_ms = timeout_ms;
492 thread.repeat = repeat;
493 thread.interp = PyThreadState_Get()->interp;
494 thread.exit = exit;
495
496 /* Arm these locks to serve as events when released */
497 PyThread_acquire_lock(thread.join_event, 1);
498 PyThread_acquire_lock(thread.cancel_event, 1);
499
500 thread.running = 1;
501 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
502 thread.running = 0;
Victor Stinnerf3091342011-04-01 03:16:51 +0200503 PyThread_release_lock(thread.join_event);
504 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200505 Py_CLEAR(thread.file);
506 PyErr_SetString(PyExc_RuntimeError,
507 "unable to start watchdog thread");
508 return NULL;
509 }
510
511 Py_RETURN_NONE;
512}
513
514static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200515faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200516{
Victor Stinner702624e2011-03-31 03:42:34 +0200517 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200518 Py_RETURN_NONE;
519}
520#endif /* FAULTHANDLER_LATER */
521
522#ifdef FAULTHANDLER_USER
523/* Handler of user signals (e.g. SIGUSR1).
524
525 Dump the traceback of the current thread, or of all threads if
526 thread.all_threads is true.
527
528 This function is signal safe and should only call signal safe functions. */
529
530static void
531faulthandler_user(int signum)
532{
533 user_signal_t *user;
534 PyThreadState *tstate;
535
536 user = &user_signals[signum];
537 if (!user->enabled)
538 return;
539
540 /* PyThreadState_Get() doesn't give the state of the current thread if
541 the thread doesn't hold the GIL. Read the thread local storage (TLS)
542 instead: call PyGILState_GetThisThreadState(). */
543 tstate = PyGILState_GetThisThreadState();
Victor Stinner024e37a2011-03-31 01:31:06 +0200544
545 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200546 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
547 else {
548 if (tstate == NULL)
549 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200550 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200551 }
552}
553
554static int
555check_signum(int signum)
556{
557 unsigned int i;
558
559 for (i=0; i < faulthandler_nsignals; i++) {
560 if (faulthandler_handlers[i].signum == signum) {
561 PyErr_Format(PyExc_RuntimeError,
562 "signal %i cannot be registered, "
563 "use enable() instead",
564 signum);
565 return 0;
566 }
567 }
568 if (signum < 1 || NSIG <= signum) {
569 PyErr_SetString(PyExc_ValueError, "signal number out of range");
570 return 0;
571 }
572 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200573}
574
575static PyObject*
576faulthandler_register(PyObject *self,
577 PyObject *args, PyObject *kwargs)
578{
579 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
580 int signum;
581 PyObject *file = NULL;
582 int all_threads = 0;
583 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200584 user_signal_t *user;
585 _Py_sighandler_t previous;
586#ifdef HAVE_SIGACTION
587 struct sigaction action;
588#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200589 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200590 int err;
591
592 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
593 "i|Oi:register", kwlist,
594 &signum, &file, &all_threads))
595 return NULL;
596
Victor Stinner44378d42011-04-01 15:37:12 +0200597 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200598 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200599
Victor Stinner44378d42011-04-01 15:37:12 +0200600 /* The caller holds the GIL and so PyThreadState_Get() can be used */
601 tstate = PyThreadState_Get();
602 if (tstate == NULL) {
603 PyErr_SetString(PyExc_RuntimeError,
604 "unable to get the current thread state");
605 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200606 }
607
608 file = faulthandler_get_fileno(file, &fd);
609 if (file == NULL)
610 return NULL;
611
612 if (user_signals == NULL) {
613 user_signals = calloc(NSIG, sizeof(user_signal_t));
614 if (user_signals == NULL)
615 return PyErr_NoMemory();
616 }
617 user = &user_signals[signum];
618
619 if (!user->enabled) {
620#ifdef HAVE_SIGACTION
621 action.sa_handler = faulthandler_user;
622 sigemptyset(&action.sa_mask);
623 /* if the signal is received while the kernel is executing a system
624 call, try to restart the system call instead of interrupting it and
625 return EINTR */
626 action.sa_flags = SA_RESTART;
627#ifdef HAVE_SIGALTSTACK
628 if (stack.ss_sp != NULL) {
629 /* Call the signal handler on an alternate signal stack
630 provided by sigaltstack() */
631 action.sa_flags |= SA_ONSTACK;
632 }
633#endif
634 err = sigaction(signum, &action, &previous);
635#else
636 previous = signal(signum, faulthandler_user);
637 err = (previous == SIG_ERR);
638#endif
639 if (err) {
640 PyErr_SetFromErrno(PyExc_OSError);
641 return NULL;
642 }
643 }
644
645 Py_XDECREF(user->file);
646 Py_INCREF(file);
647 user->file = file;
648 user->fd = fd;
649 user->all_threads = all_threads;
650 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200651 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200652 user->enabled = 1;
653
654 Py_RETURN_NONE;
655}
656
657static int
658faulthandler_unregister(user_signal_t *user, int signum)
659{
Victor Stinnera01ca122011-04-01 12:56:17 +0200660 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200661 return 0;
662 user->enabled = 0;
663#ifdef HAVE_SIGACTION
664 (void)sigaction(signum, &user->previous, NULL);
665#else
666 (void)signal(signum, user->previous);
667#endif
668 Py_CLEAR(user->file);
669 user->fd = -1;
670 return 1;
671}
672
673static PyObject*
674faulthandler_unregister_py(PyObject *self, PyObject *args)
675{
676 int signum;
677 user_signal_t *user;
678 int change;
679
680 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
681 return NULL;
682
Victor Stinner44378d42011-04-01 15:37:12 +0200683 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200684 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200685
686 user = &user_signals[signum];
687 change = faulthandler_unregister(user, signum);
688 return PyBool_FromLong(change);
689}
690#endif /* FAULTHANDLER_USER */
691
692
693static PyObject *
694faulthandler_read_null(PyObject *self, PyObject *args)
695{
696 int *x = NULL, y;
697 int release_gil = 0;
698 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
699 return NULL;
700 if (release_gil) {
701 Py_BEGIN_ALLOW_THREADS
702 y = *x;
703 Py_END_ALLOW_THREADS
704 } else
705 y = *x;
706 return PyLong_FromLong(y);
707
708}
709
710static PyObject *
711faulthandler_sigsegv(PyObject *self, PyObject *args)
712{
713#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200714 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
715 handler and then gives back the execution flow to the program (without
716 calling explicitly the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200717 SIGSEGV was raised by the kernel because of a fault, and so if the
718 program retries to execute the same instruction, the fault will be
719 raised again.
720
721 Here the fault is simulated by a fake SIGSEGV signal raised by the
722 application. We have to raise SIGSEGV at lease twice: once for
723 faulthandler_fatal_error(), and one more time for the previous signal
724 handler. */
725 while(1)
726 raise(SIGSEGV);
727#else
728 raise(SIGSEGV);
729#endif
730 Py_RETURN_NONE;
731}
732
733static PyObject *
734faulthandler_sigfpe(PyObject *self, PyObject *args)
735{
736 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
737 PowerPC. Use volatile to disable compile-time optimizations. */
738 volatile int x = 1, y = 0, z;
739 z = x / y;
740 /* if the division by zero didn't raise a SIGFPE, raise it manually */
741 raise(SIGFPE);
742 Py_RETURN_NONE;
743}
744
Victor Stinnerd727e232011-04-01 12:13:55 +0200745static PyObject *
746faulthandler_sigabrt(PyObject *self, PyObject *args)
747{
748#if _MSC_VER
749 /* If Python is compiled in debug mode with Visual Studio, abort() opens
750 a popup asking the user how to handle the assertion. Use raise(SIGABRT)
751 instead. */
752 raise(SIGABRT);
753#else
754 abort();
755#endif
756 Py_RETURN_NONE;
757}
758
Victor Stinner024e37a2011-03-31 01:31:06 +0200759#ifdef SIGBUS
760static PyObject *
761faulthandler_sigbus(PyObject *self, PyObject *args)
762{
763 raise(SIGBUS);
764 Py_RETURN_NONE;
765}
766#endif
767
768#ifdef SIGILL
769static PyObject *
770faulthandler_sigill(PyObject *self, PyObject *args)
771{
Victor Stinner024e37a2011-03-31 01:31:06 +0200772 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200773 Py_RETURN_NONE;
774}
775#endif
776
777static PyObject *
778faulthandler_fatal_error_py(PyObject *self, PyObject *args)
779{
780 char *message;
781 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
782 return NULL;
783 Py_FatalError(message);
784 Py_RETURN_NONE;
785}
786
787#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200788void*
789stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200790{
791 /* allocate 4096 bytes on the stack at each call */
792 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200793 void *sp = &buffer;
794 *depth += 1;
795 if (sp < min_sp || max_sp < sp)
796 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200797 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200798 buffer[4095] = 0;
799 return stack_overflow(min_sp, max_sp, depth);
800}
801
802static PyObject *
803faulthandler_stack_overflow(PyObject *self)
804{
805 size_t depth, size;
806 void *sp = &depth, *stop;
807
808 depth = 0;
809 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
810 sp + STACK_OVERFLOW_MAX_SIZE,
811 &depth);
812 if (sp < stop)
813 size = stop - sp;
814 else
815 size = sp - stop;
816 PyErr_Format(PyExc_RuntimeError,
817 "unable to raise a stack overflow (allocated %zu bytes "
818 "on the stack, %zu recursive calls)",
819 size, depth);
820 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200821}
822#endif
823
824
825static int
826faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
827{
828#ifdef FAULTHANDLER_USER
829 unsigned int index;
830#endif
831
832#ifdef FAULTHANDLER_LATER
833 Py_VISIT(thread.file);
834#endif
835#ifdef FAULTHANDLER_USER
836 if (user_signals != NULL) {
837 for (index=0; index < NSIG; index++)
838 Py_VISIT(user_signals[index].file);
839 }
840#endif
841 Py_VISIT(fatal_error.file);
842 return 0;
843}
844
845PyDoc_STRVAR(module_doc,
846"faulthandler module.");
847
848static PyMethodDef module_methods[] = {
849 {"enable",
850 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
851 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
852 "enable the fault handler")},
853 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
854 PyDoc_STR("disable(): disable the fault handler")},
855 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
856 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
857 {"dump_traceback",
858 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
859 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
860 "dump the traceback of the current thread, or of all threads "
861 "if all_threads is True, into file")},
862#ifdef FAULTHANDLER_LATER
863 {"dump_tracebacks_later",
864 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
865 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderr):\n"
866 "dump the traceback of all threads in timeout seconds,\n"
867 "or each timeout seconds if repeat is True.")},
868 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200869 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200870 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
871 "to dump_tracebacks_later().")},
872#endif
873
874#ifdef FAULTHANDLER_USER
875 {"register",
876 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
877 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
878 "register an handler for the signal 'signum': dump the "
879 "traceback of the current thread, or of all threads if "
880 "all_threads is True, into file")},
881 {"unregister",
882 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
883 PyDoc_STR("unregister(signum): unregister the handler of the signal "
884 "'signum' registered by register()")},
885#endif
886
887 {"_read_null", faulthandler_read_null, METH_VARARGS,
888 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
889 "a SIGSEGV or SIGBUS signal depending on the platform")},
890 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
891 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200892 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
893 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200894 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
895 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
896#ifdef SIGBUS
897 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
898 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
899#endif
900#ifdef SIGILL
901 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
902 PyDoc_STR("_sigill(): raise a SIGILL signal")},
903#endif
904 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
905 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
906#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
907 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
908 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
909#endif
910 {NULL, NULL} /* terminator */
911};
912
913static struct PyModuleDef module_def = {
914 PyModuleDef_HEAD_INIT,
915 "faulthandler",
916 module_doc,
917 0, /* non negative size to be able to unload the module */
918 module_methods,
919 NULL,
920 faulthandler_traverse,
921 NULL,
922 NULL
923};
924
925PyMODINIT_FUNC
926PyInit_faulthandler(void)
927{
928 return PyModule_Create(&module_def);
929}
930
931/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
932 defined, or if sys._xoptions has a 'faulthandler' key. */
933
934static int
935faulthandler_env_options(void)
936{
937 PyObject *xoptions, *key, *module, *res;
938 int enable;
939
940 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
941 xoptions = PySys_GetXOptions();
942 if (xoptions == NULL)
943 return -1;
944
945 key = PyUnicode_FromString("faulthandler");
946 if (key == NULL)
947 return -1;
948
949 enable = PyDict_Contains(xoptions, key);
950 Py_DECREF(key);
951 if (!enable)
952 return 0;
953 }
954 else
955 enable = 1;
956
957 module = PyImport_ImportModule("faulthandler");
958 if (module == NULL) {
959 return -1;
960 }
961 res = PyObject_CallMethod(module, "enable", "");
962 Py_DECREF(module);
963 if (res == NULL)
964 return -1;
965 Py_DECREF(res);
966 return 0;
967}
968
969int _PyFaulthandler_Init(void)
970{
971#ifdef HAVE_SIGALTSTACK
972 int err;
973
974 /* Try to allocate an alternate stack for faulthandler() signal handler to
975 * be able to allocate memory on the stack, even on a stack overflow. If it
976 * fails, ignore the error. */
977 stack.ss_flags = 0;
978 stack.ss_size = SIGSTKSZ;
979 stack.ss_sp = PyMem_Malloc(stack.ss_size);
980 if (stack.ss_sp != NULL) {
981 err = sigaltstack(&stack, NULL);
982 if (err) {
983 PyMem_Free(stack.ss_sp);
984 stack.ss_sp = NULL;
985 }
986 }
987#endif
988#ifdef FAULTHANDLER_LATER
989 thread.running = 0;
990 thread.file = NULL;
991 thread.cancel_event = PyThread_allocate_lock();
992 thread.join_event = PyThread_allocate_lock();
993 if (!thread.cancel_event || !thread.join_event) {
994 PyErr_SetString(PyExc_RuntimeError,
995 "could not allocate locks for faulthandler");
996 return -1;
997 }
998#endif
999
1000 return faulthandler_env_options();
1001}
1002
1003void _PyFaulthandler_Fini(void)
1004{
1005#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001006 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001007#endif
1008
1009#ifdef FAULTHANDLER_LATER
1010 /* later */
Victor Stinner702624e2011-03-31 03:42:34 +02001011 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001012 if (thread.cancel_event) {
1013 PyThread_free_lock(thread.cancel_event);
1014 thread.cancel_event = NULL;
1015 }
1016 if (thread.join_event) {
1017 PyThread_free_lock(thread.join_event);
1018 thread.join_event = NULL;
1019 }
1020#endif
1021
1022#ifdef FAULTHANDLER_USER
1023 /* user */
1024 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001025 for (signum=0; signum < NSIG; signum++)
1026 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001027 free(user_signals);
1028 user_signals = NULL;
1029 }
1030#endif
1031
1032 /* fatal */
1033 faulthandler_disable();
1034#ifdef HAVE_SIGALTSTACK
1035 if (stack.ss_sp != NULL) {
1036 PyMem_Free(stack.ss_sp);
1037 stack.ss_sp = NULL;
1038 }
1039#endif
1040}