blob: e8ed3e8a56685b18c4acdd57cf396d0d058b47aa [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
13 /* register() is useless on Windows, because only SIGSEGV and SIGILL can be
14 handled by the process, and these signals can only be used with enable(),
15 not using register() */
16# 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;
51 volatile int running;
52 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;
68} user_signal_t;
69
70static user_signal_t *user_signals;
71
72/* the following macros come from Python: Modules/signalmodule.c */
73#if defined(PYOS_OS2) && !defined(PYCC_GCC)
74#define NSIG 12
75#endif
76#ifndef NSIG
77# if defined(_NSIG)
78# define NSIG _NSIG /* For BSD/SysV */
79# elif defined(_SIGMAX)
80# define NSIG (_SIGMAX + 1) /* For QNX */
81# elif defined(SIGMAX)
82# define NSIG (SIGMAX + 1) /* For djgpp */
83# else
84# define NSIG 64 /* Use a reasonable default value */
85# endif
86#endif
87
88#endif /* FAULTHANDLER_USER */
89
90
91static fault_handler_t faulthandler_handlers[] = {
92#ifdef SIGBUS
93 {SIGBUS, 0, "Bus error", },
94#endif
95#ifdef SIGILL
96 {SIGILL, 0, "Illegal instruction", },
97#endif
98 {SIGFPE, 0, "Floating point exception", },
99 /* define SIGSEGV at the end to make it the default choice if searching the
100 handler fails in faulthandler_fatal_error() */
101 {SIGSEGV, 0, "Segmentation fault", }
102};
103static const unsigned char faulthandler_nsignals = \
104 sizeof(faulthandler_handlers) / sizeof(faulthandler_handlers[0]);
105
106#ifdef HAVE_SIGALTSTACK
107static stack_t stack;
108#endif
109
110
111/* Get the file descriptor of a file by calling its fileno() method and then
112 call its flush() method.
113
114 If file is NULL or Py_None, use sys.stderr as the new file.
115
116 On success, return the new file and write the file descriptor into *p_fd.
117 On error, return NULL. */
118
119static PyObject*
120faulthandler_get_fileno(PyObject *file, int *p_fd)
121{
122 PyObject *result;
123 long fd_long;
124 int fd;
125
126 if (file == NULL || file == Py_None) {
127 file = PySys_GetObject("stderr");
128 if (file == NULL) {
129 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
130 return NULL;
131 }
132 }
133
134 result = PyObject_CallMethod(file, "fileno", "");
135 if (result == NULL)
136 return NULL;
137
138 fd = -1;
139 if (PyLong_Check(result)) {
140 fd_long = PyLong_AsLong(result);
141 if (0 <= fd_long && fd_long < INT_MAX)
142 fd = (int)fd_long;
143 }
144 Py_DECREF(result);
145
146 if (fd == -1) {
147 PyErr_SetString(PyExc_RuntimeError,
148 "file.fileno() is not a valid file descriptor");
149 return NULL;
150 }
151
152 result = PyObject_CallMethod(file, "flush", "");
153 if (result != NULL)
154 Py_DECREF(result);
155 else {
156 /* ignore flush() error */
157 PyErr_Clear();
158 }
159 *p_fd = fd;
160 return file;
161}
162
163static PyObject*
164faulthandler_dump_traceback_py(PyObject *self,
165 PyObject *args, PyObject *kwargs)
166{
167 static char *kwlist[] = {"file", "all_threads", NULL};
168 PyObject *file = NULL;
169 int all_threads = 0;
170 PyThreadState *tstate;
171 const char *errmsg;
172 int fd;
173
174 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
175 "|Oi:dump_traceback", kwlist,
176 &file, &all_threads))
177 return NULL;
178
179 file = faulthandler_get_fileno(file, &fd);
180 if (file == NULL)
181 return NULL;
182
183 /* The caller holds the GIL and so PyThreadState_Get() can be used */
184 tstate = PyThreadState_Get();
185 if (tstate == NULL) {
186 PyErr_SetString(PyExc_RuntimeError,
187 "unable to get the current thread state");
188 return NULL;
189 }
190
191 if (all_threads) {
192 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
193 if (errmsg != NULL) {
194 PyErr_SetString(PyExc_RuntimeError, errmsg);
195 return NULL;
196 }
197 }
198 else {
199 _Py_DumpTraceback(fd, tstate);
200 }
201 Py_RETURN_NONE;
202}
203
204
205/* Handler of SIGSEGV, SIGFPE, SIGBUS and SIGILL signals.
206
207 Display the current Python traceback, restore the previous handler and call
208 the previous handler.
209
210 On Windows, don't call explictly the previous handler, because Windows
211 signal handler would not be called (for an unknown reason). The execution of
212 the program continues at faulthandler_fatal_error() exit, but the same
213 instruction will raise the same fault (signal), and so the previous handler
214 will be called.
215
216 This function is signal safe and should only call signal safe functions. */
217
218static void
219faulthandler_fatal_error(
220 int signum
221#ifdef HAVE_SIGACTION
222 , siginfo_t *siginfo, void *ucontext
223#endif
224)
225{
226 const int fd = fatal_error.fd;
227 unsigned int i;
228 fault_handler_t *handler = NULL;
229 PyThreadState *tstate;
230
231 if (!fatal_error.enabled)
232 return;
233
234 for (i=0; i < faulthandler_nsignals; i++) {
235 handler = &faulthandler_handlers[i];
236 if (handler->signum == signum)
237 break;
238 }
239 if (handler == NULL) {
240 /* faulthandler_nsignals == 0 (unlikely) */
241 return;
242 }
243
244 /* restore the previous handler */
245#ifdef HAVE_SIGACTION
246 (void)sigaction(handler->signum, &handler->previous, NULL);
247#else
248 (void)signal(handler->signum, handler->previous);
249#endif
250 handler->enabled = 0;
251
252 PUTS(fd, "Fatal Python error: ");
253 PUTS(fd, handler->name);
254 PUTS(fd, "\n\n");
255
256 /* SIGSEGV, SIGFPE, SIGBUS and SIGILL are synchronous signals and so are
257 delivered to the thread that caused the fault. Get the Python thread
258 state of the current thread.
259
260 PyThreadState_Get() doesn't give the state of the thread that caused the
261 fault if the thread released the GIL, and so this function cannot be
262 used. Read the thread local storage (TLS) instead: call
263 PyGILState_GetThisThreadState(). */
264 tstate = PyGILState_GetThisThreadState();
265 if (tstate == NULL)
266 return;
267
268 if (fatal_error.all_threads)
269 _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
270 else
271 _Py_DumpTraceback(fd, tstate);
272
273#ifndef MS_WINDOWS
274 /* call the previous signal handler: it is called if we use sigaction()
275 thanks to SA_NODEFER flag, otherwise it is deferred */
276 raise(signum);
277#else
278 /* on Windows, don't call explictly the previous handler, because Windows
279 signal handler would not be called */
280#endif
281}
282
283/* Install handler for fatal signals (SIGSEGV, SIGFPE, ...). */
284
285static PyObject*
286faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
287{
288 static char *kwlist[] = {"file", "all_threads", NULL};
289 PyObject *file = NULL;
290 int all_threads = 0;
291 unsigned int i;
292 fault_handler_t *handler;
293#ifdef HAVE_SIGACTION
294 struct sigaction action;
295#endif
296 int err;
297 int fd;
298
299 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
300 "|Oi:enable", kwlist, &file, &all_threads))
301 return NULL;
302
303 file = faulthandler_get_fileno(file, &fd);
304 if (file == NULL)
305 return NULL;
306
307 Py_XDECREF(fatal_error.file);
308 Py_INCREF(file);
309 fatal_error.file = file;
310 fatal_error.fd = fd;
311 fatal_error.all_threads = all_threads;
312
313 if (!fatal_error.enabled) {
314 fatal_error.enabled = 1;
315
316 for (i=0; i < faulthandler_nsignals; i++) {
317 handler = &faulthandler_handlers[i];
318#ifdef HAVE_SIGACTION
319 action.sa_sigaction = faulthandler_fatal_error;
320 sigemptyset(&action.sa_mask);
321 /* Do not prevent the signal from being received from within
322 its own signal handler */
323 action.sa_flags = SA_NODEFER;
324#ifdef HAVE_SIGALTSTACK
325 if (stack.ss_sp != NULL) {
326 /* Call the signal handler on an alternate signal stack
327 provided by sigaltstack() */
328 action.sa_flags |= SA_ONSTACK;
329 }
330#endif
331 err = sigaction(handler->signum, &action, &handler->previous);
332#else
333 handler->previous = signal(handler->signum,
334 faulthandler_fatal_error);
335 err = (handler->previous == SIG_ERR);
336#endif
337 if (err) {
338 PyErr_SetFromErrno(PyExc_RuntimeError);
339 return NULL;
340 }
341 handler->enabled = 1;
342 }
343 }
344 Py_RETURN_NONE;
345}
346
347static void
348faulthandler_disable(void)
349{
350 unsigned int i;
351 fault_handler_t *handler;
352
353 if (fatal_error.enabled) {
354 fatal_error.enabled = 0;
355 for (i=0; i < faulthandler_nsignals; i++) {
356 handler = &faulthandler_handlers[i];
357 if (!handler->enabled)
358 continue;
359#ifdef HAVE_SIGACTION
360 (void)sigaction(handler->signum, &handler->previous, NULL);
361#else
362 (void)signal(handler->signum, handler->previous);
363#endif
364 handler->enabled = 0;
365 }
366 }
367
368 Py_CLEAR(fatal_error.file);
369}
370
371static PyObject*
372faulthandler_disable_py(PyObject *self)
373{
374 if (!fatal_error.enabled) {
375 Py_INCREF(Py_False);
376 return Py_False;
377 }
378 faulthandler_disable();
379 Py_INCREF(Py_True);
380 return Py_True;
381}
382
383static PyObject*
384faulthandler_is_enabled(PyObject *self)
385{
386 return PyBool_FromLong(fatal_error.enabled);
387}
388
389#ifdef FAULTHANDLER_LATER
390
391static void
392faulthandler_thread(void *unused)
393{
394 PyLockStatus st;
395 const char* errmsg;
396 PyThreadState *current;
397 int ok;
398
399 do {
400 st = PyThread_acquire_lock_timed(thread.cancel_event,
401 thread.timeout_ms, 0);
402 if (st == PY_LOCK_ACQUIRED) {
403 /* Cancelled by user */
404 break;
405 }
406 /* Timeout => dump traceback */
407 assert(st == PY_LOCK_FAILURE);
408
409 /* get the thread holding the GIL, NULL if no thread hold the GIL */
410 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
411
412 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
413 ok = (errmsg == NULL);
414
415 if (thread.exit)
416 _exit(1);
417 } while (ok && thread.repeat);
418
419 /* The only way out */
420 thread.running = 0;
421 PyThread_release_lock(thread.join_event);
422 PyThread_release_lock(thread.cancel_event);
423}
424
425static void
Victor Stinner702624e2011-03-31 03:42:34 +0200426faulthandler_cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200427{
428 if (thread.running) {
429 /* Notify cancellation */
430 PyThread_release_lock(thread.cancel_event);
431 /* Wait for thread to join */
432 PyThread_acquire_lock(thread.join_event, 1);
433 assert(thread.running == 0);
434 PyThread_release_lock(thread.join_event);
435 }
436 Py_CLEAR(thread.file);
437}
438
439static PyObject*
440faulthandler_dump_traceback_later(PyObject *self,
441 PyObject *args, PyObject *kwargs)
442{
443 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
444 double timeout;
445 PY_TIMEOUT_T timeout_ms;
446 int repeat = 0;
447 PyObject *file = NULL;
448 int fd;
449 int exit = 0;
450
451 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
452 "d|iOi:dump_tracebacks_later", kwlist,
453 &timeout, &repeat, &file, &exit))
454 return NULL;
455 timeout *= 1e6;
456 if (timeout >= (double) PY_TIMEOUT_MAX) {
457 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
458 return NULL;
459 }
460 timeout_ms = (PY_TIMEOUT_T)timeout;
461 if (timeout_ms <= 0) {
462 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
463 return NULL;
464 }
465
466 file = faulthandler_get_fileno(file, &fd);
467 if (file == NULL)
468 return NULL;
469
470 /* Cancel previous thread, if running */
Victor Stinner702624e2011-03-31 03:42:34 +0200471 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200472
473 Py_XDECREF(thread.file);
474 Py_INCREF(file);
475 thread.file = file;
476 thread.fd = fd;
477 thread.timeout_ms = timeout_ms;
478 thread.repeat = repeat;
479 thread.interp = PyThreadState_Get()->interp;
480 thread.exit = exit;
481
482 /* Arm these locks to serve as events when released */
483 PyThread_acquire_lock(thread.join_event, 1);
484 PyThread_acquire_lock(thread.cancel_event, 1);
485
486 thread.running = 1;
487 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
488 thread.running = 0;
489 Py_CLEAR(thread.file);
490 PyErr_SetString(PyExc_RuntimeError,
491 "unable to start watchdog thread");
492 return NULL;
493 }
494
495 Py_RETURN_NONE;
496}
497
498static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200499faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200500{
Victor Stinner702624e2011-03-31 03:42:34 +0200501 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200502 Py_RETURN_NONE;
503}
504#endif /* FAULTHANDLER_LATER */
505
506#ifdef FAULTHANDLER_USER
507/* Handler of user signals (e.g. SIGUSR1).
508
509 Dump the traceback of the current thread, or of all threads if
510 thread.all_threads is true.
511
512 This function is signal safe and should only call signal safe functions. */
513
514static void
515faulthandler_user(int signum)
516{
517 user_signal_t *user;
518 PyThreadState *tstate;
519
520 user = &user_signals[signum];
521 if (!user->enabled)
522 return;
523
524 /* PyThreadState_Get() doesn't give the state of the current thread if
525 the thread doesn't hold the GIL. Read the thread local storage (TLS)
526 instead: call PyGILState_GetThisThreadState(). */
527 tstate = PyGILState_GetThisThreadState();
528 if (tstate == NULL) {
529 /* unable to get the current thread, do nothing */
530 return;
531 }
532
533 if (user->all_threads)
534 _Py_DumpTracebackThreads(user->fd, tstate->interp, tstate);
535 else
536 _Py_DumpTraceback(user->fd, tstate);
537}
538
539static PyObject*
540faulthandler_register(PyObject *self,
541 PyObject *args, PyObject *kwargs)
542{
543 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
544 int signum;
545 PyObject *file = NULL;
546 int all_threads = 0;
547 int fd;
548 unsigned int i;
549 user_signal_t *user;
550 _Py_sighandler_t previous;
551#ifdef HAVE_SIGACTION
552 struct sigaction action;
553#endif
554 int err;
555
556 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
557 "i|Oi:register", kwlist,
558 &signum, &file, &all_threads))
559 return NULL;
560
561 if (signum < 1 || NSIG <= signum) {
562 PyErr_SetString(PyExc_ValueError, "signal number out of range");
563 return NULL;
564 }
565
566 for (i=0; i < faulthandler_nsignals; i++) {
567 if (faulthandler_handlers[i].signum == signum) {
568 PyErr_Format(PyExc_RuntimeError,
569 "signal %i cannot be registered by register(), "
570 "use enable() instead",
571 signum);
572 return NULL;
573 }
574 }
575
576 file = faulthandler_get_fileno(file, &fd);
577 if (file == NULL)
578 return NULL;
579
580 if (user_signals == NULL) {
581 user_signals = calloc(NSIG, sizeof(user_signal_t));
582 if (user_signals == NULL)
583 return PyErr_NoMemory();
584 }
585 user = &user_signals[signum];
586
587 if (!user->enabled) {
588#ifdef HAVE_SIGACTION
589 action.sa_handler = faulthandler_user;
590 sigemptyset(&action.sa_mask);
591 /* if the signal is received while the kernel is executing a system
592 call, try to restart the system call instead of interrupting it and
593 return EINTR */
594 action.sa_flags = SA_RESTART;
595#ifdef HAVE_SIGALTSTACK
596 if (stack.ss_sp != NULL) {
597 /* Call the signal handler on an alternate signal stack
598 provided by sigaltstack() */
599 action.sa_flags |= SA_ONSTACK;
600 }
601#endif
602 err = sigaction(signum, &action, &previous);
603#else
604 previous = signal(signum, faulthandler_user);
605 err = (previous == SIG_ERR);
606#endif
607 if (err) {
608 PyErr_SetFromErrno(PyExc_OSError);
609 return NULL;
610 }
611 }
612
613 Py_XDECREF(user->file);
614 Py_INCREF(file);
615 user->file = file;
616 user->fd = fd;
617 user->all_threads = all_threads;
618 user->previous = previous;
619 user->enabled = 1;
620
621 Py_RETURN_NONE;
622}
623
624static int
625faulthandler_unregister(user_signal_t *user, int signum)
626{
627 if (user->enabled)
628 return 0;
629 user->enabled = 0;
630#ifdef HAVE_SIGACTION
631 (void)sigaction(signum, &user->previous, NULL);
632#else
633 (void)signal(signum, user->previous);
634#endif
635 Py_CLEAR(user->file);
636 user->fd = -1;
637 return 1;
638}
639
640static PyObject*
641faulthandler_unregister_py(PyObject *self, PyObject *args)
642{
643 int signum;
644 user_signal_t *user;
645 int change;
646
647 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
648 return NULL;
649
650 if (signum < 1 || NSIG <= signum) {
651 PyErr_SetString(PyExc_ValueError, "signal number out of range");
652 return NULL;
653 }
654
655 user = &user_signals[signum];
656 change = faulthandler_unregister(user, signum);
657 return PyBool_FromLong(change);
658}
659#endif /* FAULTHANDLER_USER */
660
661
662static PyObject *
663faulthandler_read_null(PyObject *self, PyObject *args)
664{
665 int *x = NULL, y;
666 int release_gil = 0;
667 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
668 return NULL;
669 if (release_gil) {
670 Py_BEGIN_ALLOW_THREADS
671 y = *x;
672 Py_END_ALLOW_THREADS
673 } else
674 y = *x;
675 return PyLong_FromLong(y);
676
677}
678
679static PyObject *
680faulthandler_sigsegv(PyObject *self, PyObject *args)
681{
682#if defined(MS_WINDOWS)
683 /* faulthandler_fatal_error() restores the previous signal handler and then
684 gives back the execution flow to the program. In a normal case, the
685 SIGSEGV was raised by the kernel because of a fault, and so if the
686 program retries to execute the same instruction, the fault will be
687 raised again.
688
689 Here the fault is simulated by a fake SIGSEGV signal raised by the
690 application. We have to raise SIGSEGV at lease twice: once for
691 faulthandler_fatal_error(), and one more time for the previous signal
692 handler. */
693 while(1)
694 raise(SIGSEGV);
695#else
696 raise(SIGSEGV);
697#endif
698 Py_RETURN_NONE;
699}
700
701static PyObject *
702faulthandler_sigfpe(PyObject *self, PyObject *args)
703{
704 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
705 PowerPC. Use volatile to disable compile-time optimizations. */
706 volatile int x = 1, y = 0, z;
707 z = x / y;
708 /* if the division by zero didn't raise a SIGFPE, raise it manually */
709 raise(SIGFPE);
710 Py_RETURN_NONE;
711}
712
713#ifdef SIGBUS
714static PyObject *
715faulthandler_sigbus(PyObject *self, PyObject *args)
716{
717 raise(SIGBUS);
718 Py_RETURN_NONE;
719}
720#endif
721
722#ifdef SIGILL
723static PyObject *
724faulthandler_sigill(PyObject *self, PyObject *args)
725{
726#if defined(MS_WINDOWS)
727 /* see faulthandler_sigsegv() for the explanation about while(1) */
728 while(1)
729 raise(SIGILL);
730#else
731 raise(SIGILL);
732#endif
733 Py_RETURN_NONE;
734}
735#endif
736
737static PyObject *
738faulthandler_fatal_error_py(PyObject *self, PyObject *args)
739{
740 char *message;
741 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
742 return NULL;
743 Py_FatalError(message);
744 Py_RETURN_NONE;
745}
746
747#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200748void*
749stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200750{
751 /* allocate 4096 bytes on the stack at each call */
752 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200753 void *sp = &buffer;
754 *depth += 1;
755 if (sp < min_sp || max_sp < sp)
756 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200757 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200758 buffer[4095] = 0;
759 return stack_overflow(min_sp, max_sp, depth);
760}
761
762static PyObject *
763faulthandler_stack_overflow(PyObject *self)
764{
765 size_t depth, size;
766 void *sp = &depth, *stop;
767
768 depth = 0;
769 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
770 sp + STACK_OVERFLOW_MAX_SIZE,
771 &depth);
772 if (sp < stop)
773 size = stop - sp;
774 else
775 size = sp - stop;
776 PyErr_Format(PyExc_RuntimeError,
777 "unable to raise a stack overflow (allocated %zu bytes "
778 "on the stack, %zu recursive calls)",
779 size, depth);
780 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200781}
782#endif
783
784
785static int
786faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
787{
788#ifdef FAULTHANDLER_USER
789 unsigned int index;
790#endif
791
792#ifdef FAULTHANDLER_LATER
793 Py_VISIT(thread.file);
794#endif
795#ifdef FAULTHANDLER_USER
796 if (user_signals != NULL) {
797 for (index=0; index < NSIG; index++)
798 Py_VISIT(user_signals[index].file);
799 }
800#endif
801 Py_VISIT(fatal_error.file);
802 return 0;
803}
804
805PyDoc_STRVAR(module_doc,
806"faulthandler module.");
807
808static PyMethodDef module_methods[] = {
809 {"enable",
810 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
811 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
812 "enable the fault handler")},
813 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
814 PyDoc_STR("disable(): disable the fault handler")},
815 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
816 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
817 {"dump_traceback",
818 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
819 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
820 "dump the traceback of the current thread, or of all threads "
821 "if all_threads is True, into file")},
822#ifdef FAULTHANDLER_LATER
823 {"dump_tracebacks_later",
824 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
825 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderr):\n"
826 "dump the traceback of all threads in timeout seconds,\n"
827 "or each timeout seconds if repeat is True.")},
828 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200829 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200830 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
831 "to dump_tracebacks_later().")},
832#endif
833
834#ifdef FAULTHANDLER_USER
835 {"register",
836 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
837 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
838 "register an handler for the signal 'signum': dump the "
839 "traceback of the current thread, or of all threads if "
840 "all_threads is True, into file")},
841 {"unregister",
842 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
843 PyDoc_STR("unregister(signum): unregister the handler of the signal "
844 "'signum' registered by register()")},
845#endif
846
847 {"_read_null", faulthandler_read_null, METH_VARARGS,
848 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
849 "a SIGSEGV or SIGBUS signal depending on the platform")},
850 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
851 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
852 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
853 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
854#ifdef SIGBUS
855 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
856 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
857#endif
858#ifdef SIGILL
859 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
860 PyDoc_STR("_sigill(): raise a SIGILL signal")},
861#endif
862 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
863 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
864#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
865 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
866 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
867#endif
868 {NULL, NULL} /* terminator */
869};
870
871static struct PyModuleDef module_def = {
872 PyModuleDef_HEAD_INIT,
873 "faulthandler",
874 module_doc,
875 0, /* non negative size to be able to unload the module */
876 module_methods,
877 NULL,
878 faulthandler_traverse,
879 NULL,
880 NULL
881};
882
883PyMODINIT_FUNC
884PyInit_faulthandler(void)
885{
886 return PyModule_Create(&module_def);
887}
888
889/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
890 defined, or if sys._xoptions has a 'faulthandler' key. */
891
892static int
893faulthandler_env_options(void)
894{
895 PyObject *xoptions, *key, *module, *res;
896 int enable;
897
898 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
899 xoptions = PySys_GetXOptions();
900 if (xoptions == NULL)
901 return -1;
902
903 key = PyUnicode_FromString("faulthandler");
904 if (key == NULL)
905 return -1;
906
907 enable = PyDict_Contains(xoptions, key);
908 Py_DECREF(key);
909 if (!enable)
910 return 0;
911 }
912 else
913 enable = 1;
914
915 module = PyImport_ImportModule("faulthandler");
916 if (module == NULL) {
917 return -1;
918 }
919 res = PyObject_CallMethod(module, "enable", "");
920 Py_DECREF(module);
921 if (res == NULL)
922 return -1;
923 Py_DECREF(res);
924 return 0;
925}
926
927int _PyFaulthandler_Init(void)
928{
929#ifdef HAVE_SIGALTSTACK
930 int err;
931
932 /* Try to allocate an alternate stack for faulthandler() signal handler to
933 * be able to allocate memory on the stack, even on a stack overflow. If it
934 * fails, ignore the error. */
935 stack.ss_flags = 0;
936 stack.ss_size = SIGSTKSZ;
937 stack.ss_sp = PyMem_Malloc(stack.ss_size);
938 if (stack.ss_sp != NULL) {
939 err = sigaltstack(&stack, NULL);
940 if (err) {
941 PyMem_Free(stack.ss_sp);
942 stack.ss_sp = NULL;
943 }
944 }
945#endif
946#ifdef FAULTHANDLER_LATER
947 thread.running = 0;
948 thread.file = NULL;
949 thread.cancel_event = PyThread_allocate_lock();
950 thread.join_event = PyThread_allocate_lock();
951 if (!thread.cancel_event || !thread.join_event) {
952 PyErr_SetString(PyExc_RuntimeError,
953 "could not allocate locks for faulthandler");
954 return -1;
955 }
956#endif
957
958 return faulthandler_env_options();
959}
960
961void _PyFaulthandler_Fini(void)
962{
963#ifdef FAULTHANDLER_USER
964 unsigned int i;
965#endif
966
967#ifdef FAULTHANDLER_LATER
968 /* later */
Victor Stinner702624e2011-03-31 03:42:34 +0200969 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200970 if (thread.cancel_event) {
971 PyThread_free_lock(thread.cancel_event);
972 thread.cancel_event = NULL;
973 }
974 if (thread.join_event) {
975 PyThread_free_lock(thread.join_event);
976 thread.join_event = NULL;
977 }
978#endif
979
980#ifdef FAULTHANDLER_USER
981 /* user */
982 if (user_signals != NULL) {
983 for (i=0; i < NSIG; i++)
984 faulthandler_unregister(&user_signals[i], i+1);
985 free(user_signals);
986 user_signals = NULL;
987 }
988#endif
989
990 /* fatal */
991 faulthandler_disable();
992#ifdef HAVE_SIGALTSTACK
993 if (stack.ss_sp != NULL) {
994 PyMem_Free(stack.ss_sp);
995 stack.ss_sp = NULL;
996 }
997#endif
998}