blob: 0825e842e4cef3acc6e4f928f3f596c111252d90 [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
Victor Stinner96994402011-04-07 11:37:19 +02008/* Allocate at maximum 100 MB of the stack to raise the stack overflow */
9#define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
10
Victor Stinner024e37a2011-03-31 01:31:06 +020011#ifdef WITH_THREAD
12# define FAULTHANDLER_LATER
13#endif
14
15#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020016 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
17 SIGILL can be handled by the process, and these signals can only be used
18 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020019# define FAULTHANDLER_USER
20#endif
21
22#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*
Victor Stinner96994402011-04-07 11:37:19 +0200454faulthandler_dump_tracebacks_later(PyObject *self,
455 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200456{
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;
Victor Stinner96994402011-04-07 11:37:19 +0200464 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200465
466 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
467 "d|iOi:dump_tracebacks_later", kwlist,
468 &timeout, &repeat, &file, &exit))
469 return NULL;
470 timeout *= 1e6;
471 if (timeout >= (double) PY_TIMEOUT_MAX) {
472 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
473 return NULL;
474 }
475 timeout_ms = (PY_TIMEOUT_T)timeout;
476 if (timeout_ms <= 0) {
477 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
478 return NULL;
479 }
480
Victor Stinner96994402011-04-07 11:37:19 +0200481 tstate = PyThreadState_Get();
482 if (tstate == NULL) {
483 PyErr_SetString(PyExc_RuntimeError,
484 "unable to get the current thread state");
485 return NULL;
486 }
487
Victor Stinner024e37a2011-03-31 01:31:06 +0200488 file = faulthandler_get_fileno(file, &fd);
489 if (file == NULL)
490 return NULL;
491
492 /* Cancel previous thread, if running */
Victor Stinner702624e2011-03-31 03:42:34 +0200493 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200494
495 Py_XDECREF(thread.file);
496 Py_INCREF(file);
497 thread.file = file;
498 thread.fd = fd;
499 thread.timeout_ms = timeout_ms;
500 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200501 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200502 thread.exit = exit;
503
504 /* Arm these locks to serve as events when released */
505 PyThread_acquire_lock(thread.join_event, 1);
506 PyThread_acquire_lock(thread.cancel_event, 1);
507
508 thread.running = 1;
509 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
510 thread.running = 0;
Victor Stinnerf3091342011-04-01 03:16:51 +0200511 PyThread_release_lock(thread.join_event);
512 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200513 Py_CLEAR(thread.file);
514 PyErr_SetString(PyExc_RuntimeError,
515 "unable to start watchdog thread");
516 return NULL;
517 }
518
519 Py_RETURN_NONE;
520}
521
522static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200523faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200524{
Victor Stinner702624e2011-03-31 03:42:34 +0200525 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200526 Py_RETURN_NONE;
527}
528#endif /* FAULTHANDLER_LATER */
529
530#ifdef FAULTHANDLER_USER
531/* Handler of user signals (e.g. SIGUSR1).
532
533 Dump the traceback of the current thread, or of all threads if
534 thread.all_threads is true.
535
536 This function is signal safe and should only call signal safe functions. */
537
538static void
539faulthandler_user(int signum)
540{
541 user_signal_t *user;
542 PyThreadState *tstate;
543
544 user = &user_signals[signum];
545 if (!user->enabled)
546 return;
547
548 /* PyThreadState_Get() doesn't give the state of the current thread if
549 the thread doesn't hold the GIL. Read the thread local storage (TLS)
550 instead: call PyGILState_GetThisThreadState(). */
551 tstate = PyGILState_GetThisThreadState();
Victor Stinner024e37a2011-03-31 01:31:06 +0200552
553 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200554 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
555 else {
556 if (tstate == NULL)
557 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200558 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200559 }
560}
561
562static int
563check_signum(int signum)
564{
565 unsigned int i;
566
567 for (i=0; i < faulthandler_nsignals; i++) {
568 if (faulthandler_handlers[i].signum == signum) {
569 PyErr_Format(PyExc_RuntimeError,
570 "signal %i cannot be registered, "
571 "use enable() instead",
572 signum);
573 return 0;
574 }
575 }
576 if (signum < 1 || NSIG <= signum) {
577 PyErr_SetString(PyExc_ValueError, "signal number out of range");
578 return 0;
579 }
580 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200581}
582
583static PyObject*
584faulthandler_register(PyObject *self,
585 PyObject *args, PyObject *kwargs)
586{
587 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
588 int signum;
589 PyObject *file = NULL;
590 int all_threads = 0;
591 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200592 user_signal_t *user;
593 _Py_sighandler_t previous;
594#ifdef HAVE_SIGACTION
595 struct sigaction action;
596#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200597 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200598 int err;
599
600 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
601 "i|Oi:register", kwlist,
602 &signum, &file, &all_threads))
603 return NULL;
604
Victor Stinner44378d42011-04-01 15:37:12 +0200605 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200606 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200607
Victor Stinner44378d42011-04-01 15:37:12 +0200608 /* The caller holds the GIL and so PyThreadState_Get() can be used */
609 tstate = PyThreadState_Get();
610 if (tstate == NULL) {
611 PyErr_SetString(PyExc_RuntimeError,
612 "unable to get the current thread state");
613 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200614 }
615
616 file = faulthandler_get_fileno(file, &fd);
617 if (file == NULL)
618 return NULL;
619
620 if (user_signals == NULL) {
621 user_signals = calloc(NSIG, sizeof(user_signal_t));
622 if (user_signals == NULL)
623 return PyErr_NoMemory();
624 }
625 user = &user_signals[signum];
626
627 if (!user->enabled) {
628#ifdef HAVE_SIGACTION
629 action.sa_handler = faulthandler_user;
630 sigemptyset(&action.sa_mask);
631 /* if the signal is received while the kernel is executing a system
632 call, try to restart the system call instead of interrupting it and
633 return EINTR */
634 action.sa_flags = SA_RESTART;
635#ifdef HAVE_SIGALTSTACK
636 if (stack.ss_sp != NULL) {
637 /* Call the signal handler on an alternate signal stack
638 provided by sigaltstack() */
639 action.sa_flags |= SA_ONSTACK;
640 }
641#endif
642 err = sigaction(signum, &action, &previous);
643#else
644 previous = signal(signum, faulthandler_user);
645 err = (previous == SIG_ERR);
646#endif
647 if (err) {
648 PyErr_SetFromErrno(PyExc_OSError);
649 return NULL;
650 }
651 }
652
653 Py_XDECREF(user->file);
654 Py_INCREF(file);
655 user->file = file;
656 user->fd = fd;
657 user->all_threads = all_threads;
658 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200659 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200660 user->enabled = 1;
661
662 Py_RETURN_NONE;
663}
664
665static int
666faulthandler_unregister(user_signal_t *user, int signum)
667{
Victor Stinnera01ca122011-04-01 12:56:17 +0200668 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200669 return 0;
670 user->enabled = 0;
671#ifdef HAVE_SIGACTION
672 (void)sigaction(signum, &user->previous, NULL);
673#else
674 (void)signal(signum, user->previous);
675#endif
676 Py_CLEAR(user->file);
677 user->fd = -1;
678 return 1;
679}
680
681static PyObject*
682faulthandler_unregister_py(PyObject *self, PyObject *args)
683{
684 int signum;
685 user_signal_t *user;
686 int change;
687
688 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
689 return NULL;
690
Victor Stinner44378d42011-04-01 15:37:12 +0200691 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200692 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200693
694 user = &user_signals[signum];
695 change = faulthandler_unregister(user, signum);
696 return PyBool_FromLong(change);
697}
698#endif /* FAULTHANDLER_USER */
699
700
701static PyObject *
702faulthandler_read_null(PyObject *self, PyObject *args)
703{
704 int *x = NULL, y;
705 int release_gil = 0;
706 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
707 return NULL;
708 if (release_gil) {
709 Py_BEGIN_ALLOW_THREADS
710 y = *x;
711 Py_END_ALLOW_THREADS
712 } else
713 y = *x;
714 return PyLong_FromLong(y);
715
716}
717
718static PyObject *
719faulthandler_sigsegv(PyObject *self, PyObject *args)
720{
721#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200722 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
723 handler and then gives back the execution flow to the program (without
724 calling explicitly the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200725 SIGSEGV was raised by the kernel because of a fault, and so if the
726 program retries to execute the same instruction, the fault will be
727 raised again.
728
729 Here the fault is simulated by a fake SIGSEGV signal raised by the
730 application. We have to raise SIGSEGV at lease twice: once for
731 faulthandler_fatal_error(), and one more time for the previous signal
732 handler. */
733 while(1)
734 raise(SIGSEGV);
735#else
736 raise(SIGSEGV);
737#endif
738 Py_RETURN_NONE;
739}
740
741static PyObject *
742faulthandler_sigfpe(PyObject *self, PyObject *args)
743{
744 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
745 PowerPC. Use volatile to disable compile-time optimizations. */
746 volatile int x = 1, y = 0, z;
747 z = x / y;
748 /* if the division by zero didn't raise a SIGFPE, raise it manually */
749 raise(SIGFPE);
750 Py_RETURN_NONE;
751}
752
Victor Stinnerd727e232011-04-01 12:13:55 +0200753static PyObject *
754faulthandler_sigabrt(PyObject *self, PyObject *args)
755{
756#if _MSC_VER
757 /* If Python is compiled in debug mode with Visual Studio, abort() opens
758 a popup asking the user how to handle the assertion. Use raise(SIGABRT)
759 instead. */
760 raise(SIGABRT);
761#else
762 abort();
763#endif
764 Py_RETURN_NONE;
765}
766
Victor Stinner024e37a2011-03-31 01:31:06 +0200767#ifdef SIGBUS
768static PyObject *
769faulthandler_sigbus(PyObject *self, PyObject *args)
770{
771 raise(SIGBUS);
772 Py_RETURN_NONE;
773}
774#endif
775
776#ifdef SIGILL
777static PyObject *
778faulthandler_sigill(PyObject *self, PyObject *args)
779{
Victor Stinner024e37a2011-03-31 01:31:06 +0200780 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200781 Py_RETURN_NONE;
782}
783#endif
784
785static PyObject *
786faulthandler_fatal_error_py(PyObject *self, PyObject *args)
787{
788 char *message;
789 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
790 return NULL;
791 Py_FatalError(message);
792 Py_RETURN_NONE;
793}
794
795#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200796void*
797stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200798{
799 /* allocate 4096 bytes on the stack at each call */
800 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200801 void *sp = &buffer;
802 *depth += 1;
803 if (sp < min_sp || max_sp < sp)
804 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200805 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200806 buffer[4095] = 0;
807 return stack_overflow(min_sp, max_sp, depth);
808}
809
810static PyObject *
811faulthandler_stack_overflow(PyObject *self)
812{
813 size_t depth, size;
814 void *sp = &depth, *stop;
815
816 depth = 0;
817 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
818 sp + STACK_OVERFLOW_MAX_SIZE,
819 &depth);
820 if (sp < stop)
821 size = stop - sp;
822 else
823 size = sp - stop;
824 PyErr_Format(PyExc_RuntimeError,
825 "unable to raise a stack overflow (allocated %zu bytes "
826 "on the stack, %zu recursive calls)",
827 size, depth);
828 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200829}
830#endif
831
832
833static int
834faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
835{
836#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200837 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200838#endif
839
840#ifdef FAULTHANDLER_LATER
841 Py_VISIT(thread.file);
842#endif
843#ifdef FAULTHANDLER_USER
844 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200845 for (signum=0; signum < NSIG; signum++)
846 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200847 }
848#endif
849 Py_VISIT(fatal_error.file);
850 return 0;
851}
852
853PyDoc_STRVAR(module_doc,
854"faulthandler module.");
855
856static PyMethodDef module_methods[] = {
857 {"enable",
858 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
859 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
860 "enable the fault handler")},
861 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
862 PyDoc_STR("disable(): disable the fault handler")},
863 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
864 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
865 {"dump_traceback",
866 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
867 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
868 "dump the traceback of the current thread, or of all threads "
869 "if all_threads is True, into file")},
870#ifdef FAULTHANDLER_LATER
871 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +0200872 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
873 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200874 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200875 "or each timeout seconds if repeat is True. If exit is True, "
876 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200877 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200878 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200879 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
880 "to dump_tracebacks_later().")},
881#endif
882
883#ifdef FAULTHANDLER_USER
884 {"register",
885 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
886 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
887 "register an handler for the signal 'signum': dump the "
888 "traceback of the current thread, or of all threads if "
889 "all_threads is True, into file")},
890 {"unregister",
891 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
892 PyDoc_STR("unregister(signum): unregister the handler of the signal "
893 "'signum' registered by register()")},
894#endif
895
896 {"_read_null", faulthandler_read_null, METH_VARARGS,
897 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
898 "a SIGSEGV or SIGBUS signal depending on the platform")},
899 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
900 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200901 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
902 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200903 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
904 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
905#ifdef SIGBUS
906 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
907 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
908#endif
909#ifdef SIGILL
910 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
911 PyDoc_STR("_sigill(): raise a SIGILL signal")},
912#endif
913 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
914 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
915#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
916 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
917 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
918#endif
919 {NULL, NULL} /* terminator */
920};
921
922static struct PyModuleDef module_def = {
923 PyModuleDef_HEAD_INIT,
924 "faulthandler",
925 module_doc,
926 0, /* non negative size to be able to unload the module */
927 module_methods,
928 NULL,
929 faulthandler_traverse,
930 NULL,
931 NULL
932};
933
934PyMODINIT_FUNC
935PyInit_faulthandler(void)
936{
937 return PyModule_Create(&module_def);
938}
939
940/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
941 defined, or if sys._xoptions has a 'faulthandler' key. */
942
943static int
944faulthandler_env_options(void)
945{
946 PyObject *xoptions, *key, *module, *res;
947 int enable;
948
949 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
950 xoptions = PySys_GetXOptions();
951 if (xoptions == NULL)
952 return -1;
953
954 key = PyUnicode_FromString("faulthandler");
955 if (key == NULL)
956 return -1;
957
958 enable = PyDict_Contains(xoptions, key);
959 Py_DECREF(key);
960 if (!enable)
961 return 0;
962 }
963 else
964 enable = 1;
965
966 module = PyImport_ImportModule("faulthandler");
967 if (module == NULL) {
968 return -1;
969 }
970 res = PyObject_CallMethod(module, "enable", "");
971 Py_DECREF(module);
972 if (res == NULL)
973 return -1;
974 Py_DECREF(res);
975 return 0;
976}
977
978int _PyFaulthandler_Init(void)
979{
980#ifdef HAVE_SIGALTSTACK
981 int err;
982
983 /* Try to allocate an alternate stack for faulthandler() signal handler to
984 * be able to allocate memory on the stack, even on a stack overflow. If it
985 * fails, ignore the error. */
986 stack.ss_flags = 0;
987 stack.ss_size = SIGSTKSZ;
988 stack.ss_sp = PyMem_Malloc(stack.ss_size);
989 if (stack.ss_sp != NULL) {
990 err = sigaltstack(&stack, NULL);
991 if (err) {
992 PyMem_Free(stack.ss_sp);
993 stack.ss_sp = NULL;
994 }
995 }
996#endif
997#ifdef FAULTHANDLER_LATER
998 thread.running = 0;
999 thread.file = NULL;
1000 thread.cancel_event = PyThread_allocate_lock();
1001 thread.join_event = PyThread_allocate_lock();
1002 if (!thread.cancel_event || !thread.join_event) {
1003 PyErr_SetString(PyExc_RuntimeError,
1004 "could not allocate locks for faulthandler");
1005 return -1;
1006 }
1007#endif
1008
1009 return faulthandler_env_options();
1010}
1011
1012void _PyFaulthandler_Fini(void)
1013{
1014#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001015 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001016#endif
1017
1018#ifdef FAULTHANDLER_LATER
1019 /* later */
Victor Stinner702624e2011-03-31 03:42:34 +02001020 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001021 if (thread.cancel_event) {
1022 PyThread_free_lock(thread.cancel_event);
1023 thread.cancel_event = NULL;
1024 }
1025 if (thread.join_event) {
1026 PyThread_free_lock(thread.join_event);
1027 thread.join_event = NULL;
1028 }
1029#endif
1030
1031#ifdef FAULTHANDLER_USER
1032 /* user */
1033 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001034 for (signum=0; signum < NSIG; signum++)
1035 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001036 free(user_signals);
1037 user_signals = NULL;
1038 }
1039#endif
1040
1041 /* fatal */
1042 faulthandler_disable();
1043#ifdef HAVE_SIGALTSTACK
1044 if (stack.ss_sp != NULL) {
1045 PyMem_Free(stack.ss_sp);
1046 stack.ss_sp = NULL;
1047 }
1048#endif
1049}