blob: 113203692cc663413cf512b91b38a09d55be5b96 [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
Victor Stinnercfa71232011-04-08 12:48:15 +0200697 if (user_signals == NULL)
698 Py_RETURN_FALSE;
699
Victor Stinner024e37a2011-03-31 01:31:06 +0200700 user = &user_signals[signum];
701 change = faulthandler_unregister(user, signum);
702 return PyBool_FromLong(change);
703}
704#endif /* FAULTHANDLER_USER */
705
706
707static PyObject *
708faulthandler_read_null(PyObject *self, PyObject *args)
709{
710 int *x = NULL, y;
711 int release_gil = 0;
712 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
713 return NULL;
714 if (release_gil) {
715 Py_BEGIN_ALLOW_THREADS
716 y = *x;
717 Py_END_ALLOW_THREADS
718 } else
719 y = *x;
720 return PyLong_FromLong(y);
721
722}
723
724static PyObject *
725faulthandler_sigsegv(PyObject *self, PyObject *args)
726{
727#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200728 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
729 handler and then gives back the execution flow to the program (without
730 calling explicitly the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200731 SIGSEGV was raised by the kernel because of a fault, and so if the
732 program retries to execute the same instruction, the fault will be
733 raised again.
734
735 Here the fault is simulated by a fake SIGSEGV signal raised by the
736 application. We have to raise SIGSEGV at lease twice: once for
737 faulthandler_fatal_error(), and one more time for the previous signal
738 handler. */
739 while(1)
740 raise(SIGSEGV);
741#else
742 raise(SIGSEGV);
743#endif
744 Py_RETURN_NONE;
745}
746
747static PyObject *
748faulthandler_sigfpe(PyObject *self, PyObject *args)
749{
750 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
751 PowerPC. Use volatile to disable compile-time optimizations. */
752 volatile int x = 1, y = 0, z;
753 z = x / y;
754 /* if the division by zero didn't raise a SIGFPE, raise it manually */
755 raise(SIGFPE);
756 Py_RETURN_NONE;
757}
758
Victor Stinnerd727e232011-04-01 12:13:55 +0200759static PyObject *
760faulthandler_sigabrt(PyObject *self, PyObject *args)
761{
762#if _MSC_VER
763 /* If Python is compiled in debug mode with Visual Studio, abort() opens
764 a popup asking the user how to handle the assertion. Use raise(SIGABRT)
765 instead. */
766 raise(SIGABRT);
767#else
768 abort();
769#endif
770 Py_RETURN_NONE;
771}
772
Victor Stinner024e37a2011-03-31 01:31:06 +0200773#ifdef SIGBUS
774static PyObject *
775faulthandler_sigbus(PyObject *self, PyObject *args)
776{
777 raise(SIGBUS);
778 Py_RETURN_NONE;
779}
780#endif
781
782#ifdef SIGILL
783static PyObject *
784faulthandler_sigill(PyObject *self, PyObject *args)
785{
Victor Stinner024e37a2011-03-31 01:31:06 +0200786 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200787 Py_RETURN_NONE;
788}
789#endif
790
791static PyObject *
792faulthandler_fatal_error_py(PyObject *self, PyObject *args)
793{
794 char *message;
795 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
796 return NULL;
797 Py_FatalError(message);
798 Py_RETURN_NONE;
799}
800
801#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200802void*
803stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200804{
805 /* allocate 4096 bytes on the stack at each call */
806 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200807 void *sp = &buffer;
808 *depth += 1;
809 if (sp < min_sp || max_sp < sp)
810 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200811 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200812 buffer[4095] = 0;
813 return stack_overflow(min_sp, max_sp, depth);
814}
815
816static PyObject *
817faulthandler_stack_overflow(PyObject *self)
818{
819 size_t depth, size;
820 void *sp = &depth, *stop;
821
822 depth = 0;
823 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
824 sp + STACK_OVERFLOW_MAX_SIZE,
825 &depth);
826 if (sp < stop)
827 size = stop - sp;
828 else
829 size = sp - stop;
830 PyErr_Format(PyExc_RuntimeError,
831 "unable to raise a stack overflow (allocated %zu bytes "
832 "on the stack, %zu recursive calls)",
833 size, depth);
834 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200835}
836#endif
837
838
839static int
840faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
841{
842#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200843 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200844#endif
845
846#ifdef FAULTHANDLER_LATER
847 Py_VISIT(thread.file);
848#endif
849#ifdef FAULTHANDLER_USER
850 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200851 for (signum=0; signum < NSIG; signum++)
852 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200853 }
854#endif
855 Py_VISIT(fatal_error.file);
856 return 0;
857}
858
859PyDoc_STRVAR(module_doc,
860"faulthandler module.");
861
862static PyMethodDef module_methods[] = {
863 {"enable",
864 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
865 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
866 "enable the fault handler")},
867 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
868 PyDoc_STR("disable(): disable the fault handler")},
869 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
870 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
871 {"dump_traceback",
872 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
873 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
874 "dump the traceback of the current thread, or of all threads "
875 "if all_threads is True, into file")},
876#ifdef FAULTHANDLER_LATER
877 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +0200878 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
879 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200880 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200881 "or each timeout seconds if repeat is True. If exit is True, "
882 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200883 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200884 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200885 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
886 "to dump_tracebacks_later().")},
887#endif
888
889#ifdef FAULTHANDLER_USER
890 {"register",
891 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
892 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
893 "register an handler for the signal 'signum': dump the "
894 "traceback of the current thread, or of all threads if "
895 "all_threads is True, into file")},
896 {"unregister",
897 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
898 PyDoc_STR("unregister(signum): unregister the handler of the signal "
899 "'signum' registered by register()")},
900#endif
901
902 {"_read_null", faulthandler_read_null, METH_VARARGS,
903 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
904 "a SIGSEGV or SIGBUS signal depending on the platform")},
905 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
906 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200907 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
908 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200909 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
910 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
911#ifdef SIGBUS
912 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
913 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
914#endif
915#ifdef SIGILL
916 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
917 PyDoc_STR("_sigill(): raise a SIGILL signal")},
918#endif
919 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
920 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
921#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
922 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
923 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
924#endif
925 {NULL, NULL} /* terminator */
926};
927
928static struct PyModuleDef module_def = {
929 PyModuleDef_HEAD_INIT,
930 "faulthandler",
931 module_doc,
932 0, /* non negative size to be able to unload the module */
933 module_methods,
934 NULL,
935 faulthandler_traverse,
936 NULL,
937 NULL
938};
939
940PyMODINIT_FUNC
941PyInit_faulthandler(void)
942{
943 return PyModule_Create(&module_def);
944}
945
946/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
947 defined, or if sys._xoptions has a 'faulthandler' key. */
948
949static int
950faulthandler_env_options(void)
951{
952 PyObject *xoptions, *key, *module, *res;
953 int enable;
954
955 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
956 xoptions = PySys_GetXOptions();
957 if (xoptions == NULL)
958 return -1;
959
960 key = PyUnicode_FromString("faulthandler");
961 if (key == NULL)
962 return -1;
963
964 enable = PyDict_Contains(xoptions, key);
965 Py_DECREF(key);
966 if (!enable)
967 return 0;
968 }
969 else
970 enable = 1;
971
972 module = PyImport_ImportModule("faulthandler");
973 if (module == NULL) {
974 return -1;
975 }
976 res = PyObject_CallMethod(module, "enable", "");
977 Py_DECREF(module);
978 if (res == NULL)
979 return -1;
980 Py_DECREF(res);
981 return 0;
982}
983
984int _PyFaulthandler_Init(void)
985{
986#ifdef HAVE_SIGALTSTACK
987 int err;
988
989 /* Try to allocate an alternate stack for faulthandler() signal handler to
990 * be able to allocate memory on the stack, even on a stack overflow. If it
991 * fails, ignore the error. */
992 stack.ss_flags = 0;
993 stack.ss_size = SIGSTKSZ;
994 stack.ss_sp = PyMem_Malloc(stack.ss_size);
995 if (stack.ss_sp != NULL) {
996 err = sigaltstack(&stack, NULL);
997 if (err) {
998 PyMem_Free(stack.ss_sp);
999 stack.ss_sp = NULL;
1000 }
1001 }
1002#endif
1003#ifdef FAULTHANDLER_LATER
1004 thread.running = 0;
1005 thread.file = NULL;
1006 thread.cancel_event = PyThread_allocate_lock();
1007 thread.join_event = PyThread_allocate_lock();
1008 if (!thread.cancel_event || !thread.join_event) {
1009 PyErr_SetString(PyExc_RuntimeError,
1010 "could not allocate locks for faulthandler");
1011 return -1;
1012 }
1013#endif
1014
1015 return faulthandler_env_options();
1016}
1017
1018void _PyFaulthandler_Fini(void)
1019{
1020#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001021 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001022#endif
1023
1024#ifdef FAULTHANDLER_LATER
1025 /* later */
Victor Stinner702624e2011-03-31 03:42:34 +02001026 faulthandler_cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001027 if (thread.cancel_event) {
1028 PyThread_free_lock(thread.cancel_event);
1029 thread.cancel_event = NULL;
1030 }
1031 if (thread.join_event) {
1032 PyThread_free_lock(thread.join_event);
1033 thread.join_event = NULL;
1034 }
1035#endif
1036
1037#ifdef FAULTHANDLER_USER
1038 /* user */
1039 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001040 for (signum=0; signum < NSIG; signum++)
1041 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001042 free(user_signals);
1043 user_signals = NULL;
1044 }
1045#endif
1046
1047 /* fatal */
1048 faulthandler_disable();
1049#ifdef HAVE_SIGALTSTACK
1050 if (stack.ss_sp != NULL) {
1051 PyMem_Free(stack.ss_sp);
1052 stack.ss_sp = NULL;
1053 }
1054#endif
1055}