blob: cfbfda6192d696a9af63a6212bdc795498a27cb2 [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
Victor Stinner44e31ba2011-04-07 11:39:03 +0200221faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200222{
223 const int fd = fatal_error.fd;
224 unsigned int i;
225 fault_handler_t *handler = NULL;
226 PyThreadState *tstate;
227
228 if (!fatal_error.enabled)
229 return;
230
231 for (i=0; i < faulthandler_nsignals; i++) {
232 handler = &faulthandler_handlers[i];
233 if (handler->signum == signum)
234 break;
235 }
236 if (handler == NULL) {
237 /* faulthandler_nsignals == 0 (unlikely) */
238 return;
239 }
240
241 /* restore the previous handler */
242#ifdef HAVE_SIGACTION
243 (void)sigaction(handler->signum, &handler->previous, NULL);
244#else
245 (void)signal(handler->signum, handler->previous);
246#endif
247 handler->enabled = 0;
248
249 PUTS(fd, "Fatal Python error: ");
250 PUTS(fd, handler->name);
251 PUTS(fd, "\n\n");
252
Victor Stinnerd727e232011-04-01 12:13:55 +0200253 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
254 so are delivered to the thread that caused the fault. Get the Python
255 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200256
257 PyThreadState_Get() doesn't give the state of the thread that caused the
258 fault if the thread released the GIL, and so this function cannot be
259 used. Read the thread local storage (TLS) instead: call
260 PyGILState_GetThisThreadState(). */
261 tstate = PyGILState_GetThisThreadState();
262 if (tstate == NULL)
263 return;
264
265 if (fatal_error.all_threads)
266 _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
267 else
268 _Py_DumpTraceback(fd, tstate);
269
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200270#ifdef MS_WINDOWS
271 if (signum == SIGSEGV) {
272 /* don't call explictly the previous handler for SIGSEGV in this signal
273 handler, because the Windows signal handler would not be called */
274 return;
275 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200276#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200277 /* call the previous signal handler: it is called immediatly if we use
278 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
279 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200280}
281
Victor Stinnerd727e232011-04-01 12:13:55 +0200282/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200283
284static PyObject*
285faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
286{
287 static char *kwlist[] = {"file", "all_threads", NULL};
288 PyObject *file = NULL;
289 int all_threads = 0;
290 unsigned int i;
291 fault_handler_t *handler;
292#ifdef HAVE_SIGACTION
293 struct sigaction action;
294#endif
295 int err;
296 int fd;
297
298 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
299 "|Oi:enable", kwlist, &file, &all_threads))
300 return NULL;
301
302 file = faulthandler_get_fileno(file, &fd);
303 if (file == NULL)
304 return NULL;
305
306 Py_XDECREF(fatal_error.file);
307 Py_INCREF(file);
308 fatal_error.file = file;
309 fatal_error.fd = fd;
310 fatal_error.all_threads = all_threads;
311
312 if (!fatal_error.enabled) {
313 fatal_error.enabled = 1;
314
315 for (i=0; i < faulthandler_nsignals; i++) {
316 handler = &faulthandler_handlers[i];
317#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200318 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200319 sigemptyset(&action.sa_mask);
320 /* Do not prevent the signal from being received from within
321 its own signal handler */
322 action.sa_flags = SA_NODEFER;
323#ifdef HAVE_SIGALTSTACK
324 if (stack.ss_sp != NULL) {
325 /* Call the signal handler on an alternate signal stack
326 provided by sigaltstack() */
327 action.sa_flags |= SA_ONSTACK;
328 }
329#endif
330 err = sigaction(handler->signum, &action, &handler->previous);
331#else
332 handler->previous = signal(handler->signum,
333 faulthandler_fatal_error);
334 err = (handler->previous == SIG_ERR);
335#endif
336 if (err) {
337 PyErr_SetFromErrno(PyExc_RuntimeError);
338 return NULL;
339 }
340 handler->enabled = 1;
341 }
342 }
343 Py_RETURN_NONE;
344}
345
346static void
347faulthandler_disable(void)
348{
349 unsigned int i;
350 fault_handler_t *handler;
351
352 if (fatal_error.enabled) {
353 fatal_error.enabled = 0;
354 for (i=0; i < faulthandler_nsignals; i++) {
355 handler = &faulthandler_handlers[i];
356 if (!handler->enabled)
357 continue;
358#ifdef HAVE_SIGACTION
359 (void)sigaction(handler->signum, &handler->previous, NULL);
360#else
361 (void)signal(handler->signum, handler->previous);
362#endif
363 handler->enabled = 0;
364 }
365 }
366
367 Py_CLEAR(fatal_error.file);
368}
369
370static PyObject*
371faulthandler_disable_py(PyObject *self)
372{
373 if (!fatal_error.enabled) {
374 Py_INCREF(Py_False);
375 return Py_False;
376 }
377 faulthandler_disable();
378 Py_INCREF(Py_True);
379 return Py_True;
380}
381
382static PyObject*
383faulthandler_is_enabled(PyObject *self)
384{
385 return PyBool_FromLong(fatal_error.enabled);
386}
387
388#ifdef FAULTHANDLER_LATER
389
390static void
391faulthandler_thread(void *unused)
392{
393 PyLockStatus st;
394 const char* errmsg;
395 PyThreadState *current;
396 int ok;
Victor Stinnerda9edae2011-04-04 11:05:21 +0200397#ifdef HAVE_PTHREAD_H
398 sigset_t set;
399
400 /* we don't want to receive any signal */
401 sigfillset(&set);
402#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
403 pthread_sigmask(SIG_SETMASK, &set, NULL);
404#else
405 sigprocmask(SIG_SETMASK, &set, NULL);
406#endif
407#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200408
409 do {
410 st = PyThread_acquire_lock_timed(thread.cancel_event,
411 thread.timeout_ms, 0);
412 if (st == PY_LOCK_ACQUIRED) {
413 /* Cancelled by user */
414 break;
415 }
416 /* Timeout => dump traceback */
417 assert(st == PY_LOCK_FAILURE);
418
419 /* get the thread holding the GIL, NULL if no thread hold the GIL */
420 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
421
422 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
423 ok = (errmsg == NULL);
424
425 if (thread.exit)
426 _exit(1);
427 } while (ok && thread.repeat);
428
429 /* The only way out */
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200430 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200431 PyThread_release_lock(thread.join_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200432}
433
434static void
Victor Stinner702624e2011-03-31 03:42:34 +0200435faulthandler_cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200436{
437 if (thread.running) {
438 /* Notify cancellation */
439 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200440 }
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200441 /* Wait for thread to join */
442 PyThread_acquire_lock(thread.join_event, 1);
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200443 PyThread_release_lock(thread.join_event);
Victor Stinnerf3091342011-04-01 03:16:51 +0200444 thread.running = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200445 Py_CLEAR(thread.file);
446}
447
448static PyObject*
Victor Stinner96994402011-04-07 11:37:19 +0200449faulthandler_dump_tracebacks_later(PyObject *self,
450 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200451{
452 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
453 double timeout;
454 PY_TIMEOUT_T timeout_ms;
455 int repeat = 0;
456 PyObject *file = NULL;
457 int fd;
458 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200459 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200460
461 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
462 "d|iOi:dump_tracebacks_later", kwlist,
463 &timeout, &repeat, &file, &exit))
464 return NULL;
465 timeout *= 1e6;
466 if (timeout >= (double) PY_TIMEOUT_MAX) {
467 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
468 return NULL;
469 }
470 timeout_ms = (PY_TIMEOUT_T)timeout;
471 if (timeout_ms <= 0) {
472 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
473 return NULL;
474 }
475
Victor Stinner96994402011-04-07 11:37:19 +0200476 tstate = PyThreadState_Get();
477 if (tstate == NULL) {
478 PyErr_SetString(PyExc_RuntimeError,
479 "unable to get the current thread state");
480 return NULL;
481 }
482
Victor Stinner024e37a2011-03-31 01:31:06 +0200483 file = faulthandler_get_fileno(file, &fd);
484 if (file == NULL)
485 return NULL;
486
487 /* Cancel previous thread, if running */
Victor Stinner702624e2011-03-31 03:42:34 +0200488 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200489
490 Py_XDECREF(thread.file);
491 Py_INCREF(file);
492 thread.file = file;
493 thread.fd = fd;
494 thread.timeout_ms = timeout_ms;
495 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200496 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200497 thread.exit = exit;
498
499 /* Arm these locks to serve as events when released */
500 PyThread_acquire_lock(thread.join_event, 1);
501 PyThread_acquire_lock(thread.cancel_event, 1);
502
503 thread.running = 1;
504 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
505 thread.running = 0;
Victor Stinnerf3091342011-04-01 03:16:51 +0200506 PyThread_release_lock(thread.join_event);
507 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200508 Py_CLEAR(thread.file);
509 PyErr_SetString(PyExc_RuntimeError,
510 "unable to start watchdog thread");
511 return NULL;
512 }
513
514 Py_RETURN_NONE;
515}
516
517static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200518faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200519{
Victor Stinner702624e2011-03-31 03:42:34 +0200520 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200521 Py_RETURN_NONE;
522}
523#endif /* FAULTHANDLER_LATER */
524
525#ifdef FAULTHANDLER_USER
526/* Handler of user signals (e.g. SIGUSR1).
527
528 Dump the traceback of the current thread, or of all threads if
529 thread.all_threads is true.
530
531 This function is signal safe and should only call signal safe functions. */
532
533static void
534faulthandler_user(int signum)
535{
536 user_signal_t *user;
537 PyThreadState *tstate;
538
539 user = &user_signals[signum];
540 if (!user->enabled)
541 return;
542
543 /* PyThreadState_Get() doesn't give the state of the current thread if
544 the thread doesn't hold the GIL. Read the thread local storage (TLS)
545 instead: call PyGILState_GetThisThreadState(). */
546 tstate = PyGILState_GetThisThreadState();
Victor Stinner024e37a2011-03-31 01:31:06 +0200547
548 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200549 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
550 else {
551 if (tstate == NULL)
552 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200553 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200554 }
555}
556
557static int
558check_signum(int signum)
559{
560 unsigned int i;
561
562 for (i=0; i < faulthandler_nsignals; i++) {
563 if (faulthandler_handlers[i].signum == signum) {
564 PyErr_Format(PyExc_RuntimeError,
565 "signal %i cannot be registered, "
566 "use enable() instead",
567 signum);
568 return 0;
569 }
570 }
571 if (signum < 1 || NSIG <= signum) {
572 PyErr_SetString(PyExc_ValueError, "signal number out of range");
573 return 0;
574 }
575 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200576}
577
578static PyObject*
579faulthandler_register(PyObject *self,
580 PyObject *args, PyObject *kwargs)
581{
582 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
583 int signum;
584 PyObject *file = NULL;
585 int all_threads = 0;
586 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200587 user_signal_t *user;
588 _Py_sighandler_t previous;
589#ifdef HAVE_SIGACTION
590 struct sigaction action;
591#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200592 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200593 int err;
594
595 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
596 "i|Oi:register", kwlist,
597 &signum, &file, &all_threads))
598 return NULL;
599
Victor Stinner44378d42011-04-01 15:37:12 +0200600 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200601 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200602
Victor Stinner44378d42011-04-01 15:37:12 +0200603 /* The caller holds the GIL and so PyThreadState_Get() can be used */
604 tstate = PyThreadState_Get();
605 if (tstate == NULL) {
606 PyErr_SetString(PyExc_RuntimeError,
607 "unable to get the current thread state");
608 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200609 }
610
611 file = faulthandler_get_fileno(file, &fd);
612 if (file == NULL)
613 return NULL;
614
615 if (user_signals == NULL) {
616 user_signals = calloc(NSIG, sizeof(user_signal_t));
617 if (user_signals == NULL)
618 return PyErr_NoMemory();
619 }
620 user = &user_signals[signum];
621
622 if (!user->enabled) {
623#ifdef HAVE_SIGACTION
624 action.sa_handler = faulthandler_user;
625 sigemptyset(&action.sa_mask);
626 /* if the signal is received while the kernel is executing a system
627 call, try to restart the system call instead of interrupting it and
628 return EINTR */
629 action.sa_flags = SA_RESTART;
630#ifdef HAVE_SIGALTSTACK
631 if (stack.ss_sp != NULL) {
632 /* Call the signal handler on an alternate signal stack
633 provided by sigaltstack() */
634 action.sa_flags |= SA_ONSTACK;
635 }
636#endif
637 err = sigaction(signum, &action, &previous);
638#else
639 previous = signal(signum, faulthandler_user);
640 err = (previous == SIG_ERR);
641#endif
642 if (err) {
643 PyErr_SetFromErrno(PyExc_OSError);
644 return NULL;
645 }
646 }
647
648 Py_XDECREF(user->file);
649 Py_INCREF(file);
650 user->file = file;
651 user->fd = fd;
652 user->all_threads = all_threads;
653 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200654 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200655 user->enabled = 1;
656
657 Py_RETURN_NONE;
658}
659
660static int
661faulthandler_unregister(user_signal_t *user, int signum)
662{
Victor Stinnera01ca122011-04-01 12:56:17 +0200663 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200664 return 0;
665 user->enabled = 0;
666#ifdef HAVE_SIGACTION
667 (void)sigaction(signum, &user->previous, NULL);
668#else
669 (void)signal(signum, user->previous);
670#endif
671 Py_CLEAR(user->file);
672 user->fd = -1;
673 return 1;
674}
675
676static PyObject*
677faulthandler_unregister_py(PyObject *self, PyObject *args)
678{
679 int signum;
680 user_signal_t *user;
681 int change;
682
683 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
684 return NULL;
685
Victor Stinner44378d42011-04-01 15:37:12 +0200686 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200687 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200688
689 user = &user_signals[signum];
690 change = faulthandler_unregister(user, signum);
691 return PyBool_FromLong(change);
692}
693#endif /* FAULTHANDLER_USER */
694
695
696static PyObject *
697faulthandler_read_null(PyObject *self, PyObject *args)
698{
699 int *x = NULL, y;
700 int release_gil = 0;
701 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
702 return NULL;
703 if (release_gil) {
704 Py_BEGIN_ALLOW_THREADS
705 y = *x;
706 Py_END_ALLOW_THREADS
707 } else
708 y = *x;
709 return PyLong_FromLong(y);
710
711}
712
713static PyObject *
714faulthandler_sigsegv(PyObject *self, PyObject *args)
715{
716#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200717 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
718 handler and then gives back the execution flow to the program (without
719 calling explicitly the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200720 SIGSEGV was raised by the kernel because of a fault, and so if the
721 program retries to execute the same instruction, the fault will be
722 raised again.
723
724 Here the fault is simulated by a fake SIGSEGV signal raised by the
725 application. We have to raise SIGSEGV at lease twice: once for
726 faulthandler_fatal_error(), and one more time for the previous signal
727 handler. */
728 while(1)
729 raise(SIGSEGV);
730#else
731 raise(SIGSEGV);
732#endif
733 Py_RETURN_NONE;
734}
735
736static PyObject *
737faulthandler_sigfpe(PyObject *self, PyObject *args)
738{
739 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
740 PowerPC. Use volatile to disable compile-time optimizations. */
741 volatile int x = 1, y = 0, z;
742 z = x / y;
743 /* if the division by zero didn't raise a SIGFPE, raise it manually */
744 raise(SIGFPE);
745 Py_RETURN_NONE;
746}
747
Victor Stinnerd727e232011-04-01 12:13:55 +0200748static PyObject *
749faulthandler_sigabrt(PyObject *self, PyObject *args)
750{
751#if _MSC_VER
752 /* If Python is compiled in debug mode with Visual Studio, abort() opens
753 a popup asking the user how to handle the assertion. Use raise(SIGABRT)
754 instead. */
755 raise(SIGABRT);
756#else
757 abort();
758#endif
759 Py_RETURN_NONE;
760}
761
Victor Stinner024e37a2011-03-31 01:31:06 +0200762#ifdef SIGBUS
763static PyObject *
764faulthandler_sigbus(PyObject *self, PyObject *args)
765{
766 raise(SIGBUS);
767 Py_RETURN_NONE;
768}
769#endif
770
771#ifdef SIGILL
772static PyObject *
773faulthandler_sigill(PyObject *self, PyObject *args)
774{
Victor Stinner024e37a2011-03-31 01:31:06 +0200775 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200776 Py_RETURN_NONE;
777}
778#endif
779
780static PyObject *
781faulthandler_fatal_error_py(PyObject *self, PyObject *args)
782{
783 char *message;
784 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
785 return NULL;
786 Py_FatalError(message);
787 Py_RETURN_NONE;
788}
789
790#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200791void*
792stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200793{
794 /* allocate 4096 bytes on the stack at each call */
795 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200796 void *sp = &buffer;
797 *depth += 1;
798 if (sp < min_sp || max_sp < sp)
799 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200800 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200801 buffer[4095] = 0;
802 return stack_overflow(min_sp, max_sp, depth);
803}
804
805static PyObject *
806faulthandler_stack_overflow(PyObject *self)
807{
808 size_t depth, size;
809 void *sp = &depth, *stop;
810
811 depth = 0;
812 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
813 sp + STACK_OVERFLOW_MAX_SIZE,
814 &depth);
815 if (sp < stop)
816 size = stop - sp;
817 else
818 size = sp - stop;
819 PyErr_Format(PyExc_RuntimeError,
820 "unable to raise a stack overflow (allocated %zu bytes "
821 "on the stack, %zu recursive calls)",
822 size, depth);
823 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200824}
825#endif
826
827
828static int
829faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
830{
831#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200832 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200833#endif
834
835#ifdef FAULTHANDLER_LATER
836 Py_VISIT(thread.file);
837#endif
838#ifdef FAULTHANDLER_USER
839 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200840 for (signum=0; signum < NSIG; signum++)
841 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200842 }
843#endif
844 Py_VISIT(fatal_error.file);
845 return 0;
846}
847
848PyDoc_STRVAR(module_doc,
849"faulthandler module.");
850
851static PyMethodDef module_methods[] = {
852 {"enable",
853 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
854 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
855 "enable the fault handler")},
856 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
857 PyDoc_STR("disable(): disable the fault handler")},
858 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
859 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
860 {"dump_traceback",
861 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
862 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
863 "dump the traceback of the current thread, or of all threads "
864 "if all_threads is True, into file")},
865#ifdef FAULTHANDLER_LATER
866 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +0200867 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
868 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200869 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200870 "or each timeout seconds if repeat is True. If exit is True, "
871 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200872 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200873 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200874 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
875 "to dump_tracebacks_later().")},
876#endif
877
878#ifdef FAULTHANDLER_USER
879 {"register",
880 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
881 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
882 "register an handler for the signal 'signum': dump the "
883 "traceback of the current thread, or of all threads if "
884 "all_threads is True, into file")},
885 {"unregister",
886 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
887 PyDoc_STR("unregister(signum): unregister the handler of the signal "
888 "'signum' registered by register()")},
889#endif
890
891 {"_read_null", faulthandler_read_null, METH_VARARGS,
892 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
893 "a SIGSEGV or SIGBUS signal depending on the platform")},
894 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
895 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200896 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
897 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200898 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
899 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
900#ifdef SIGBUS
901 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
902 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
903#endif
904#ifdef SIGILL
905 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
906 PyDoc_STR("_sigill(): raise a SIGILL signal")},
907#endif
908 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
909 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
910#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
911 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
912 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
913#endif
914 {NULL, NULL} /* terminator */
915};
916
917static struct PyModuleDef module_def = {
918 PyModuleDef_HEAD_INIT,
919 "faulthandler",
920 module_doc,
921 0, /* non negative size to be able to unload the module */
922 module_methods,
923 NULL,
924 faulthandler_traverse,
925 NULL,
926 NULL
927};
928
929PyMODINIT_FUNC
930PyInit_faulthandler(void)
931{
932 return PyModule_Create(&module_def);
933}
934
935/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
936 defined, or if sys._xoptions has a 'faulthandler' key. */
937
938static int
939faulthandler_env_options(void)
940{
941 PyObject *xoptions, *key, *module, *res;
942 int enable;
943
944 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
945 xoptions = PySys_GetXOptions();
946 if (xoptions == NULL)
947 return -1;
948
949 key = PyUnicode_FromString("faulthandler");
950 if (key == NULL)
951 return -1;
952
953 enable = PyDict_Contains(xoptions, key);
954 Py_DECREF(key);
955 if (!enable)
956 return 0;
957 }
958 else
959 enable = 1;
960
961 module = PyImport_ImportModule("faulthandler");
962 if (module == NULL) {
963 return -1;
964 }
965 res = PyObject_CallMethod(module, "enable", "");
966 Py_DECREF(module);
967 if (res == NULL)
968 return -1;
969 Py_DECREF(res);
970 return 0;
971}
972
973int _PyFaulthandler_Init(void)
974{
975#ifdef HAVE_SIGALTSTACK
976 int err;
977
978 /* Try to allocate an alternate stack for faulthandler() signal handler to
979 * be able to allocate memory on the stack, even on a stack overflow. If it
980 * fails, ignore the error. */
981 stack.ss_flags = 0;
982 stack.ss_size = SIGSTKSZ;
983 stack.ss_sp = PyMem_Malloc(stack.ss_size);
984 if (stack.ss_sp != NULL) {
985 err = sigaltstack(&stack, NULL);
986 if (err) {
987 PyMem_Free(stack.ss_sp);
988 stack.ss_sp = NULL;
989 }
990 }
991#endif
992#ifdef FAULTHANDLER_LATER
993 thread.running = 0;
994 thread.file = NULL;
995 thread.cancel_event = PyThread_allocate_lock();
996 thread.join_event = PyThread_allocate_lock();
997 if (!thread.cancel_event || !thread.join_event) {
998 PyErr_SetString(PyExc_RuntimeError,
999 "could not allocate locks for faulthandler");
1000 return -1;
1001 }
1002#endif
1003
1004 return faulthandler_env_options();
1005}
1006
1007void _PyFaulthandler_Fini(void)
1008{
1009#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001010 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001011#endif
1012
1013#ifdef FAULTHANDLER_LATER
1014 /* later */
Victor Stinner702624e2011-03-31 03:42:34 +02001015 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001016 if (thread.cancel_event) {
1017 PyThread_free_lock(thread.cancel_event);
1018 thread.cancel_event = NULL;
1019 }
1020 if (thread.join_event) {
1021 PyThread_free_lock(thread.join_event);
1022 thread.join_event = NULL;
1023 }
1024#endif
1025
1026#ifdef FAULTHANDLER_USER
1027 /* user */
1028 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001029 for (signum=0; signum < NSIG; signum++)
1030 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001031 free(user_signals);
1032 user_signals = NULL;
1033 }
1034#endif
1035
1036 /* fatal */
1037 faulthandler_disable();
1038#ifdef HAVE_SIGALTSTACK
1039 if (stack.ss_sp != NULL) {
1040 PyMem_Free(stack.ss_sp);
1041 stack.ss_sp = NULL;
1042 }
1043#endif
1044}