blob: 76cadf382c541ca92e2257f9a57bbb673e671070 [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 Stinnerff4cd882011-04-07 11:50:25 +0200253#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200254 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
255 so are delivered to the thread that caused the fault. Get the Python
256 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200257
258 PyThreadState_Get() doesn't give the state of the thread that caused the
259 fault if the thread released the GIL, and so this function cannot be
260 used. Read the thread local storage (TLS) instead: call
261 PyGILState_GetThisThreadState(). */
262 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200263#else
264 tstate = PyThreadState_Get();
265#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200266 if (tstate == NULL)
267 return;
268
269 if (fatal_error.all_threads)
270 _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
271 else
272 _Py_DumpTraceback(fd, tstate);
273
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200274#ifdef MS_WINDOWS
275 if (signum == SIGSEGV) {
276 /* don't call explictly the previous handler for SIGSEGV in this signal
277 handler, because the Windows signal handler would not be called */
278 return;
279 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200280#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200281 /* call the previous signal handler: it is called immediatly if we use
282 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
283 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200284}
285
Victor Stinnerd727e232011-04-01 12:13:55 +0200286/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200287
288static PyObject*
289faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
290{
291 static char *kwlist[] = {"file", "all_threads", NULL};
292 PyObject *file = NULL;
293 int all_threads = 0;
294 unsigned int i;
295 fault_handler_t *handler;
296#ifdef HAVE_SIGACTION
297 struct sigaction action;
298#endif
299 int err;
300 int fd;
301
302 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
303 "|Oi:enable", kwlist, &file, &all_threads))
304 return NULL;
305
306 file = faulthandler_get_fileno(file, &fd);
307 if (file == NULL)
308 return NULL;
309
310 Py_XDECREF(fatal_error.file);
311 Py_INCREF(file);
312 fatal_error.file = file;
313 fatal_error.fd = fd;
314 fatal_error.all_threads = all_threads;
315
316 if (!fatal_error.enabled) {
317 fatal_error.enabled = 1;
318
319 for (i=0; i < faulthandler_nsignals; i++) {
320 handler = &faulthandler_handlers[i];
321#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200322 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200323 sigemptyset(&action.sa_mask);
324 /* Do not prevent the signal from being received from within
325 its own signal handler */
326 action.sa_flags = SA_NODEFER;
327#ifdef HAVE_SIGALTSTACK
328 if (stack.ss_sp != NULL) {
329 /* Call the signal handler on an alternate signal stack
330 provided by sigaltstack() */
331 action.sa_flags |= SA_ONSTACK;
332 }
333#endif
334 err = sigaction(handler->signum, &action, &handler->previous);
335#else
336 handler->previous = signal(handler->signum,
337 faulthandler_fatal_error);
338 err = (handler->previous == SIG_ERR);
339#endif
340 if (err) {
341 PyErr_SetFromErrno(PyExc_RuntimeError);
342 return NULL;
343 }
344 handler->enabled = 1;
345 }
346 }
347 Py_RETURN_NONE;
348}
349
350static void
351faulthandler_disable(void)
352{
353 unsigned int i;
354 fault_handler_t *handler;
355
356 if (fatal_error.enabled) {
357 fatal_error.enabled = 0;
358 for (i=0; i < faulthandler_nsignals; i++) {
359 handler = &faulthandler_handlers[i];
360 if (!handler->enabled)
361 continue;
362#ifdef HAVE_SIGACTION
363 (void)sigaction(handler->signum, &handler->previous, NULL);
364#else
365 (void)signal(handler->signum, handler->previous);
366#endif
367 handler->enabled = 0;
368 }
369 }
370
371 Py_CLEAR(fatal_error.file);
372}
373
374static PyObject*
375faulthandler_disable_py(PyObject *self)
376{
377 if (!fatal_error.enabled) {
378 Py_INCREF(Py_False);
379 return Py_False;
380 }
381 faulthandler_disable();
382 Py_INCREF(Py_True);
383 return Py_True;
384}
385
386static PyObject*
387faulthandler_is_enabled(PyObject *self)
388{
389 return PyBool_FromLong(fatal_error.enabled);
390}
391
392#ifdef FAULTHANDLER_LATER
393
394static void
395faulthandler_thread(void *unused)
396{
397 PyLockStatus st;
398 const char* errmsg;
399 PyThreadState *current;
400 int ok;
Victor Stinnerda9edae2011-04-04 11:05:21 +0200401#ifdef HAVE_PTHREAD_H
402 sigset_t set;
403
404 /* we don't want to receive any signal */
405 sigfillset(&set);
406#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
407 pthread_sigmask(SIG_SETMASK, &set, NULL);
408#else
409 sigprocmask(SIG_SETMASK, &set, NULL);
410#endif
411#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200412
413 do {
414 st = PyThread_acquire_lock_timed(thread.cancel_event,
415 thread.timeout_ms, 0);
416 if (st == PY_LOCK_ACQUIRED) {
417 /* Cancelled by user */
418 break;
419 }
420 /* Timeout => dump traceback */
421 assert(st == PY_LOCK_FAILURE);
422
423 /* get the thread holding the GIL, NULL if no thread hold the GIL */
424 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
425
426 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
427 ok = (errmsg == NULL);
428
429 if (thread.exit)
430 _exit(1);
431 } while (ok && thread.repeat);
432
433 /* The only way out */
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200434 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200435 PyThread_release_lock(thread.join_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200436}
437
438static void
Victor Stinner702624e2011-03-31 03:42:34 +0200439faulthandler_cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200440{
441 if (thread.running) {
442 /* Notify cancellation */
443 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200444 }
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200445 /* Wait for thread to join */
446 PyThread_acquire_lock(thread.join_event, 1);
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200447 PyThread_release_lock(thread.join_event);
Victor Stinnerf3091342011-04-01 03:16:51 +0200448 thread.running = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200449 Py_CLEAR(thread.file);
450}
451
452static PyObject*
Victor Stinner96994402011-04-07 11:37:19 +0200453faulthandler_dump_tracebacks_later(PyObject *self,
454 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200455{
456 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
457 double timeout;
458 PY_TIMEOUT_T timeout_ms;
459 int repeat = 0;
460 PyObject *file = NULL;
461 int fd;
462 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200463 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200464
465 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
466 "d|iOi:dump_tracebacks_later", kwlist,
467 &timeout, &repeat, &file, &exit))
468 return NULL;
469 timeout *= 1e6;
470 if (timeout >= (double) PY_TIMEOUT_MAX) {
471 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
472 return NULL;
473 }
474 timeout_ms = (PY_TIMEOUT_T)timeout;
475 if (timeout_ms <= 0) {
476 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
477 return NULL;
478 }
479
Victor Stinner96994402011-04-07 11:37:19 +0200480 tstate = PyThreadState_Get();
481 if (tstate == NULL) {
482 PyErr_SetString(PyExc_RuntimeError,
483 "unable to get the current thread state");
484 return NULL;
485 }
486
Victor Stinner024e37a2011-03-31 01:31:06 +0200487 file = faulthandler_get_fileno(file, &fd);
488 if (file == NULL)
489 return NULL;
490
491 /* Cancel previous thread, if running */
Victor Stinner702624e2011-03-31 03:42:34 +0200492 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200493
494 Py_XDECREF(thread.file);
495 Py_INCREF(file);
496 thread.file = file;
497 thread.fd = fd;
498 thread.timeout_ms = timeout_ms;
499 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200500 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200501 thread.exit = exit;
502
503 /* Arm these locks to serve as events when released */
504 PyThread_acquire_lock(thread.join_event, 1);
505 PyThread_acquire_lock(thread.cancel_event, 1);
506
507 thread.running = 1;
508 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
509 thread.running = 0;
Victor Stinnerf3091342011-04-01 03:16:51 +0200510 PyThread_release_lock(thread.join_event);
511 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200512 Py_CLEAR(thread.file);
513 PyErr_SetString(PyExc_RuntimeError,
514 "unable to start watchdog thread");
515 return NULL;
516 }
517
518 Py_RETURN_NONE;
519}
520
521static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200522faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200523{
Victor Stinner702624e2011-03-31 03:42:34 +0200524 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200525 Py_RETURN_NONE;
526}
527#endif /* FAULTHANDLER_LATER */
528
529#ifdef FAULTHANDLER_USER
530/* Handler of user signals (e.g. SIGUSR1).
531
532 Dump the traceback of the current thread, or of all threads if
533 thread.all_threads is true.
534
535 This function is signal safe and should only call signal safe functions. */
536
537static void
538faulthandler_user(int signum)
539{
540 user_signal_t *user;
541 PyThreadState *tstate;
542
543 user = &user_signals[signum];
544 if (!user->enabled)
545 return;
546
Victor Stinnerff4cd882011-04-07 11:50:25 +0200547#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200548 /* 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 Stinnerff4cd882011-04-07 11:50:25 +0200552#else
553 tstate = PyThreadState_Get();
554#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200555
556 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200557 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
558 else {
559 if (tstate == NULL)
560 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200561 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200562 }
563}
564
565static int
566check_signum(int signum)
567{
568 unsigned int i;
569
570 for (i=0; i < faulthandler_nsignals; i++) {
571 if (faulthandler_handlers[i].signum == signum) {
572 PyErr_Format(PyExc_RuntimeError,
573 "signal %i cannot be registered, "
574 "use enable() instead",
575 signum);
576 return 0;
577 }
578 }
579 if (signum < 1 || NSIG <= signum) {
580 PyErr_SetString(PyExc_ValueError, "signal number out of range");
581 return 0;
582 }
583 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200584}
585
586static PyObject*
587faulthandler_register(PyObject *self,
588 PyObject *args, PyObject *kwargs)
589{
590 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
591 int signum;
592 PyObject *file = NULL;
593 int all_threads = 0;
594 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200595 user_signal_t *user;
596 _Py_sighandler_t previous;
597#ifdef HAVE_SIGACTION
598 struct sigaction action;
599#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200600 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200601 int err;
602
603 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
604 "i|Oi:register", kwlist,
605 &signum, &file, &all_threads))
606 return NULL;
607
Victor Stinner44378d42011-04-01 15:37:12 +0200608 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200609 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200610
Victor Stinner44378d42011-04-01 15:37:12 +0200611 /* The caller holds the GIL and so PyThreadState_Get() can be used */
612 tstate = PyThreadState_Get();
613 if (tstate == NULL) {
614 PyErr_SetString(PyExc_RuntimeError,
615 "unable to get the current thread state");
616 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200617 }
618
619 file = faulthandler_get_fileno(file, &fd);
620 if (file == NULL)
621 return NULL;
622
623 if (user_signals == NULL) {
624 user_signals = calloc(NSIG, sizeof(user_signal_t));
625 if (user_signals == NULL)
626 return PyErr_NoMemory();
627 }
628 user = &user_signals[signum];
629
630 if (!user->enabled) {
631#ifdef HAVE_SIGACTION
632 action.sa_handler = faulthandler_user;
633 sigemptyset(&action.sa_mask);
634 /* if the signal is received while the kernel is executing a system
635 call, try to restart the system call instead of interrupting it and
636 return EINTR */
637 action.sa_flags = SA_RESTART;
638#ifdef HAVE_SIGALTSTACK
639 if (stack.ss_sp != NULL) {
640 /* Call the signal handler on an alternate signal stack
641 provided by sigaltstack() */
642 action.sa_flags |= SA_ONSTACK;
643 }
644#endif
645 err = sigaction(signum, &action, &previous);
646#else
647 previous = signal(signum, faulthandler_user);
648 err = (previous == SIG_ERR);
649#endif
650 if (err) {
651 PyErr_SetFromErrno(PyExc_OSError);
652 return NULL;
653 }
654 }
655
656 Py_XDECREF(user->file);
657 Py_INCREF(file);
658 user->file = file;
659 user->fd = fd;
660 user->all_threads = all_threads;
661 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200662 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200663 user->enabled = 1;
664
665 Py_RETURN_NONE;
666}
667
668static int
669faulthandler_unregister(user_signal_t *user, int signum)
670{
Victor Stinnera01ca122011-04-01 12:56:17 +0200671 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200672 return 0;
673 user->enabled = 0;
674#ifdef HAVE_SIGACTION
675 (void)sigaction(signum, &user->previous, NULL);
676#else
677 (void)signal(signum, user->previous);
678#endif
679 Py_CLEAR(user->file);
680 user->fd = -1;
681 return 1;
682}
683
684static PyObject*
685faulthandler_unregister_py(PyObject *self, PyObject *args)
686{
687 int signum;
688 user_signal_t *user;
689 int change;
690
691 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
692 return NULL;
693
Victor Stinner44378d42011-04-01 15:37:12 +0200694 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200695 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200696
697 user = &user_signals[signum];
698 change = faulthandler_unregister(user, signum);
699 return PyBool_FromLong(change);
700}
701#endif /* FAULTHANDLER_USER */
702
703
704static PyObject *
705faulthandler_read_null(PyObject *self, PyObject *args)
706{
707 int *x = NULL, y;
708 int release_gil = 0;
709 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
710 return NULL;
711 if (release_gil) {
712 Py_BEGIN_ALLOW_THREADS
713 y = *x;
714 Py_END_ALLOW_THREADS
715 } else
716 y = *x;
717 return PyLong_FromLong(y);
718
719}
720
721static PyObject *
722faulthandler_sigsegv(PyObject *self, PyObject *args)
723{
724#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200725 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
726 handler and then gives back the execution flow to the program (without
727 calling explicitly the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200728 SIGSEGV was raised by the kernel because of a fault, and so if the
729 program retries to execute the same instruction, the fault will be
730 raised again.
731
732 Here the fault is simulated by a fake SIGSEGV signal raised by the
733 application. We have to raise SIGSEGV at lease twice: once for
734 faulthandler_fatal_error(), and one more time for the previous signal
735 handler. */
736 while(1)
737 raise(SIGSEGV);
738#else
739 raise(SIGSEGV);
740#endif
741 Py_RETURN_NONE;
742}
743
744static PyObject *
745faulthandler_sigfpe(PyObject *self, PyObject *args)
746{
747 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
748 PowerPC. Use volatile to disable compile-time optimizations. */
749 volatile int x = 1, y = 0, z;
750 z = x / y;
751 /* if the division by zero didn't raise a SIGFPE, raise it manually */
752 raise(SIGFPE);
753 Py_RETURN_NONE;
754}
755
Victor Stinnerd727e232011-04-01 12:13:55 +0200756static PyObject *
757faulthandler_sigabrt(PyObject *self, PyObject *args)
758{
759#if _MSC_VER
760 /* If Python is compiled in debug mode with Visual Studio, abort() opens
761 a popup asking the user how to handle the assertion. Use raise(SIGABRT)
762 instead. */
763 raise(SIGABRT);
764#else
765 abort();
766#endif
767 Py_RETURN_NONE;
768}
769
Victor Stinner024e37a2011-03-31 01:31:06 +0200770#ifdef SIGBUS
771static PyObject *
772faulthandler_sigbus(PyObject *self, PyObject *args)
773{
774 raise(SIGBUS);
775 Py_RETURN_NONE;
776}
777#endif
778
779#ifdef SIGILL
780static PyObject *
781faulthandler_sigill(PyObject *self, PyObject *args)
782{
Victor Stinner024e37a2011-03-31 01:31:06 +0200783 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200784 Py_RETURN_NONE;
785}
786#endif
787
788static PyObject *
789faulthandler_fatal_error_py(PyObject *self, PyObject *args)
790{
791 char *message;
792 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
793 return NULL;
794 Py_FatalError(message);
795 Py_RETURN_NONE;
796}
797
798#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200799void*
800stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200801{
802 /* allocate 4096 bytes on the stack at each call */
803 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200804 void *sp = &buffer;
805 *depth += 1;
806 if (sp < min_sp || max_sp < sp)
807 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200808 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200809 buffer[4095] = 0;
810 return stack_overflow(min_sp, max_sp, depth);
811}
812
813static PyObject *
814faulthandler_stack_overflow(PyObject *self)
815{
816 size_t depth, size;
817 void *sp = &depth, *stop;
818
819 depth = 0;
820 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
821 sp + STACK_OVERFLOW_MAX_SIZE,
822 &depth);
823 if (sp < stop)
824 size = stop - sp;
825 else
826 size = sp - stop;
827 PyErr_Format(PyExc_RuntimeError,
828 "unable to raise a stack overflow (allocated %zu bytes "
829 "on the stack, %zu recursive calls)",
830 size, depth);
831 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200832}
833#endif
834
835
836static int
837faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
838{
839#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200840 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200841#endif
842
843#ifdef FAULTHANDLER_LATER
844 Py_VISIT(thread.file);
845#endif
846#ifdef FAULTHANDLER_USER
847 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200848 for (signum=0; signum < NSIG; signum++)
849 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200850 }
851#endif
852 Py_VISIT(fatal_error.file);
853 return 0;
854}
855
856PyDoc_STRVAR(module_doc,
857"faulthandler module.");
858
859static PyMethodDef module_methods[] = {
860 {"enable",
861 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
862 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
863 "enable the fault handler")},
864 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
865 PyDoc_STR("disable(): disable the fault handler")},
866 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
867 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
868 {"dump_traceback",
869 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
870 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
871 "dump the traceback of the current thread, or of all threads "
872 "if all_threads is True, into file")},
873#ifdef FAULTHANDLER_LATER
874 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +0200875 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
876 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200877 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200878 "or each timeout seconds if repeat is True. If exit is True, "
879 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200880 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200881 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200882 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
883 "to dump_tracebacks_later().")},
884#endif
885
886#ifdef FAULTHANDLER_USER
887 {"register",
888 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
889 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
890 "register an handler for the signal 'signum': dump the "
891 "traceback of the current thread, or of all threads if "
892 "all_threads is True, into file")},
893 {"unregister",
894 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
895 PyDoc_STR("unregister(signum): unregister the handler of the signal "
896 "'signum' registered by register()")},
897#endif
898
899 {"_read_null", faulthandler_read_null, METH_VARARGS,
900 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
901 "a SIGSEGV or SIGBUS signal depending on the platform")},
902 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
903 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200904 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
905 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200906 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
907 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
908#ifdef SIGBUS
909 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
910 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
911#endif
912#ifdef SIGILL
913 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
914 PyDoc_STR("_sigill(): raise a SIGILL signal")},
915#endif
916 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
917 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
918#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
919 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
920 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
921#endif
922 {NULL, NULL} /* terminator */
923};
924
925static struct PyModuleDef module_def = {
926 PyModuleDef_HEAD_INIT,
927 "faulthandler",
928 module_doc,
929 0, /* non negative size to be able to unload the module */
930 module_methods,
931 NULL,
932 faulthandler_traverse,
933 NULL,
934 NULL
935};
936
937PyMODINIT_FUNC
938PyInit_faulthandler(void)
939{
940 return PyModule_Create(&module_def);
941}
942
943/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
944 defined, or if sys._xoptions has a 'faulthandler' key. */
945
946static int
947faulthandler_env_options(void)
948{
949 PyObject *xoptions, *key, *module, *res;
950 int enable;
951
952 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
953 xoptions = PySys_GetXOptions();
954 if (xoptions == NULL)
955 return -1;
956
957 key = PyUnicode_FromString("faulthandler");
958 if (key == NULL)
959 return -1;
960
961 enable = PyDict_Contains(xoptions, key);
962 Py_DECREF(key);
963 if (!enable)
964 return 0;
965 }
966 else
967 enable = 1;
968
969 module = PyImport_ImportModule("faulthandler");
970 if (module == NULL) {
971 return -1;
972 }
973 res = PyObject_CallMethod(module, "enable", "");
974 Py_DECREF(module);
975 if (res == NULL)
976 return -1;
977 Py_DECREF(res);
978 return 0;
979}
980
981int _PyFaulthandler_Init(void)
982{
983#ifdef HAVE_SIGALTSTACK
984 int err;
985
986 /* Try to allocate an alternate stack for faulthandler() signal handler to
987 * be able to allocate memory on the stack, even on a stack overflow. If it
988 * fails, ignore the error. */
989 stack.ss_flags = 0;
990 stack.ss_size = SIGSTKSZ;
991 stack.ss_sp = PyMem_Malloc(stack.ss_size);
992 if (stack.ss_sp != NULL) {
993 err = sigaltstack(&stack, NULL);
994 if (err) {
995 PyMem_Free(stack.ss_sp);
996 stack.ss_sp = NULL;
997 }
998 }
999#endif
1000#ifdef FAULTHANDLER_LATER
1001 thread.running = 0;
1002 thread.file = NULL;
1003 thread.cancel_event = PyThread_allocate_lock();
1004 thread.join_event = PyThread_allocate_lock();
1005 if (!thread.cancel_event || !thread.join_event) {
1006 PyErr_SetString(PyExc_RuntimeError,
1007 "could not allocate locks for faulthandler");
1008 return -1;
1009 }
1010#endif
1011
1012 return faulthandler_env_options();
1013}
1014
1015void _PyFaulthandler_Fini(void)
1016{
1017#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001018 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001019#endif
1020
1021#ifdef FAULTHANDLER_LATER
1022 /* later */
Victor Stinner702624e2011-03-31 03:42:34 +02001023 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001024 if (thread.cancel_event) {
1025 PyThread_free_lock(thread.cancel_event);
1026 thread.cancel_event = NULL;
1027 }
1028 if (thread.join_event) {
1029 PyThread_free_lock(thread.join_event);
1030 thread.join_event = NULL;
1031 }
1032#endif
1033
1034#ifdef FAULTHANDLER_USER
1035 /* user */
1036 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001037 for (signum=0; signum < NSIG; signum++)
1038 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001039 free(user_signals);
1040 user_signals = NULL;
1041 }
1042#endif
1043
1044 /* fatal */
1045 faulthandler_disable();
1046#ifdef HAVE_SIGALTSTACK
1047 if (stack.ss_sp != NULL) {
1048 PyMem_Free(stack.ss_sp);
1049 stack.ss_sp = NULL;
1050 }
1051#endif
1052}