blob: d2852f9ab58016b4640bb88662057cb4075d9469 [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 Stinner024e37a2011-03-31 01:31:06 +020051 PyInterpreterState *interp;
52 int exit;
Victor Stinnerde10f402011-04-08 12:57:06 +020053 /* The main thread always hold this lock. It is only released when
54 faulthandler_thread() is interrupted until this thread exits, or at
55 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020056 PyThread_type_lock cancel_event;
57 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020058 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020059} thread;
60#endif
61
62#ifdef FAULTHANDLER_USER
63typedef struct {
64 int enabled;
65 PyObject *file;
66 int fd;
67 int all_threads;
68 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020069 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020070} user_signal_t;
71
72static user_signal_t *user_signals;
73
74/* the following macros come from Python: Modules/signalmodule.c */
75#if defined(PYOS_OS2) && !defined(PYCC_GCC)
76#define NSIG 12
77#endif
78#ifndef NSIG
79# if defined(_NSIG)
80# define NSIG _NSIG /* For BSD/SysV */
81# elif defined(_SIGMAX)
82# define NSIG (_SIGMAX + 1) /* For QNX */
83# elif defined(SIGMAX)
84# define NSIG (SIGMAX + 1) /* For djgpp */
85# else
86# define NSIG 64 /* Use a reasonable default value */
87# endif
88#endif
89
90#endif /* FAULTHANDLER_USER */
91
92
93static fault_handler_t faulthandler_handlers[] = {
94#ifdef SIGBUS
95 {SIGBUS, 0, "Bus error", },
96#endif
97#ifdef SIGILL
98 {SIGILL, 0, "Illegal instruction", },
99#endif
100 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200101 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200102 /* define SIGSEGV at the end to make it the default choice if searching the
103 handler fails in faulthandler_fatal_error() */
104 {SIGSEGV, 0, "Segmentation fault", }
105};
106static const unsigned char faulthandler_nsignals = \
107 sizeof(faulthandler_handlers) / sizeof(faulthandler_handlers[0]);
108
109#ifdef HAVE_SIGALTSTACK
110static stack_t stack;
111#endif
112
113
114/* Get the file descriptor of a file by calling its fileno() method and then
115 call its flush() method.
116
117 If file is NULL or Py_None, use sys.stderr as the new file.
118
119 On success, return the new file and write the file descriptor into *p_fd.
120 On error, return NULL. */
121
122static PyObject*
123faulthandler_get_fileno(PyObject *file, int *p_fd)
124{
125 PyObject *result;
126 long fd_long;
127 int fd;
128
129 if (file == NULL || file == Py_None) {
130 file = PySys_GetObject("stderr");
131 if (file == NULL) {
132 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
133 return NULL;
134 }
135 }
136
137 result = PyObject_CallMethod(file, "fileno", "");
138 if (result == NULL)
139 return NULL;
140
141 fd = -1;
142 if (PyLong_Check(result)) {
143 fd_long = PyLong_AsLong(result);
144 if (0 <= fd_long && fd_long < INT_MAX)
145 fd = (int)fd_long;
146 }
147 Py_DECREF(result);
148
149 if (fd == -1) {
150 PyErr_SetString(PyExc_RuntimeError,
151 "file.fileno() is not a valid file descriptor");
152 return NULL;
153 }
154
155 result = PyObject_CallMethod(file, "flush", "");
156 if (result != NULL)
157 Py_DECREF(result);
158 else {
159 /* ignore flush() error */
160 PyErr_Clear();
161 }
162 *p_fd = fd;
163 return file;
164}
165
166static PyObject*
167faulthandler_dump_traceback_py(PyObject *self,
168 PyObject *args, PyObject *kwargs)
169{
170 static char *kwlist[] = {"file", "all_threads", NULL};
171 PyObject *file = NULL;
172 int all_threads = 0;
173 PyThreadState *tstate;
174 const char *errmsg;
175 int fd;
176
177 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
178 "|Oi:dump_traceback", kwlist,
179 &file, &all_threads))
180 return NULL;
181
182 file = faulthandler_get_fileno(file, &fd);
183 if (file == NULL)
184 return NULL;
185
186 /* The caller holds the GIL and so PyThreadState_Get() can be used */
187 tstate = PyThreadState_Get();
188 if (tstate == NULL) {
189 PyErr_SetString(PyExc_RuntimeError,
190 "unable to get the current thread state");
191 return NULL;
192 }
193
194 if (all_threads) {
195 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
196 if (errmsg != NULL) {
197 PyErr_SetString(PyExc_RuntimeError, errmsg);
198 return NULL;
199 }
200 }
201 else {
202 _Py_DumpTraceback(fd, tstate);
203 }
204 Py_RETURN_NONE;
205}
206
207
Victor Stinnerd727e232011-04-01 12:13:55 +0200208/* Handler of SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200209
210 Display the current Python traceback, restore the previous handler and call
211 the previous handler.
212
213 On Windows, don't call explictly the previous handler, because Windows
214 signal handler would not be called (for an unknown reason). The execution of
215 the program continues at faulthandler_fatal_error() exit, but the same
216 instruction will raise the same fault (signal), and so the previous handler
217 will be called.
218
219 This function is signal safe and should only call signal safe functions. */
220
221static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200222faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200223{
224 const int fd = fatal_error.fd;
225 unsigned int i;
226 fault_handler_t *handler = NULL;
227 PyThreadState *tstate;
228
229 if (!fatal_error.enabled)
230 return;
231
232 for (i=0; i < faulthandler_nsignals; i++) {
233 handler = &faulthandler_handlers[i];
234 if (handler->signum == signum)
235 break;
236 }
237 if (handler == NULL) {
238 /* faulthandler_nsignals == 0 (unlikely) */
239 return;
240 }
241
242 /* restore the previous handler */
243#ifdef HAVE_SIGACTION
244 (void)sigaction(handler->signum, &handler->previous, NULL);
245#else
246 (void)signal(handler->signum, handler->previous);
247#endif
248 handler->enabled = 0;
249
250 PUTS(fd, "Fatal Python error: ");
251 PUTS(fd, handler->name);
252 PUTS(fd, "\n\n");
253
Victor Stinnerff4cd882011-04-07 11:50:25 +0200254#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200255 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
256 so are delivered to the thread that caused the fault. Get the Python
257 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200258
259 PyThreadState_Get() doesn't give the state of the thread that caused the
260 fault if the thread released the GIL, and so this function cannot be
261 used. Read the thread local storage (TLS) instead: call
262 PyGILState_GetThisThreadState(). */
263 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200264#else
265 tstate = PyThreadState_Get();
266#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200267 if (tstate == NULL)
268 return;
269
270 if (fatal_error.all_threads)
271 _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
272 else
273 _Py_DumpTraceback(fd, tstate);
274
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200275#ifdef MS_WINDOWS
276 if (signum == SIGSEGV) {
277 /* don't call explictly the previous handler for SIGSEGV in this signal
278 handler, because the Windows signal handler would not be called */
279 return;
280 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200281#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200282 /* call the previous signal handler: it is called immediatly if we use
283 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
284 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200285}
286
Victor Stinnerd727e232011-04-01 12:13:55 +0200287/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200288
289static PyObject*
290faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
291{
292 static char *kwlist[] = {"file", "all_threads", NULL};
293 PyObject *file = NULL;
294 int all_threads = 0;
295 unsigned int i;
296 fault_handler_t *handler;
297#ifdef HAVE_SIGACTION
298 struct sigaction action;
299#endif
300 int err;
301 int fd;
302
303 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
304 "|Oi:enable", kwlist, &file, &all_threads))
305 return NULL;
306
307 file = faulthandler_get_fileno(file, &fd);
308 if (file == NULL)
309 return NULL;
310
311 Py_XDECREF(fatal_error.file);
312 Py_INCREF(file);
313 fatal_error.file = file;
314 fatal_error.fd = fd;
315 fatal_error.all_threads = all_threads;
316
317 if (!fatal_error.enabled) {
318 fatal_error.enabled = 1;
319
320 for (i=0; i < faulthandler_nsignals; i++) {
321 handler = &faulthandler_handlers[i];
322#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200323 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200324 sigemptyset(&action.sa_mask);
325 /* Do not prevent the signal from being received from within
326 its own signal handler */
327 action.sa_flags = SA_NODEFER;
328#ifdef HAVE_SIGALTSTACK
329 if (stack.ss_sp != NULL) {
330 /* Call the signal handler on an alternate signal stack
331 provided by sigaltstack() */
332 action.sa_flags |= SA_ONSTACK;
333 }
334#endif
335 err = sigaction(handler->signum, &action, &handler->previous);
336#else
337 handler->previous = signal(handler->signum,
338 faulthandler_fatal_error);
339 err = (handler->previous == SIG_ERR);
340#endif
341 if (err) {
342 PyErr_SetFromErrno(PyExc_RuntimeError);
343 return NULL;
344 }
345 handler->enabled = 1;
346 }
347 }
348 Py_RETURN_NONE;
349}
350
351static void
352faulthandler_disable(void)
353{
354 unsigned int i;
355 fault_handler_t *handler;
356
357 if (fatal_error.enabled) {
358 fatal_error.enabled = 0;
359 for (i=0; i < faulthandler_nsignals; i++) {
360 handler = &faulthandler_handlers[i];
361 if (!handler->enabled)
362 continue;
363#ifdef HAVE_SIGACTION
364 (void)sigaction(handler->signum, &handler->previous, NULL);
365#else
366 (void)signal(handler->signum, handler->previous);
367#endif
368 handler->enabled = 0;
369 }
370 }
371
372 Py_CLEAR(fatal_error.file);
373}
374
375static PyObject*
376faulthandler_disable_py(PyObject *self)
377{
378 if (!fatal_error.enabled) {
379 Py_INCREF(Py_False);
380 return Py_False;
381 }
382 faulthandler_disable();
383 Py_INCREF(Py_True);
384 return Py_True;
385}
386
387static PyObject*
388faulthandler_is_enabled(PyObject *self)
389{
390 return PyBool_FromLong(fatal_error.enabled);
391}
392
393#ifdef FAULTHANDLER_LATER
394
395static void
396faulthandler_thread(void *unused)
397{
398 PyLockStatus st;
399 const char* errmsg;
400 PyThreadState *current;
401 int ok;
Victor Stinnerda9edae2011-04-04 11:05:21 +0200402#ifdef HAVE_PTHREAD_H
403 sigset_t set;
404
405 /* we don't want to receive any signal */
406 sigfillset(&set);
407#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
408 pthread_sigmask(SIG_SETMASK, &set, NULL);
409#else
410 sigprocmask(SIG_SETMASK, &set, NULL);
411#endif
412#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200413
414 do {
415 st = PyThread_acquire_lock_timed(thread.cancel_event,
416 thread.timeout_ms, 0);
417 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200418 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200419 break;
420 }
421 /* Timeout => dump traceback */
422 assert(st == PY_LOCK_FAILURE);
423
424 /* get the thread holding the GIL, NULL if no thread hold the GIL */
425 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
426
427 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
428 ok = (errmsg == NULL);
429
430 if (thread.exit)
431 _exit(1);
432 } while (ok && thread.repeat);
433
434 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200435 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200436}
437
438static void
Victor Stinnerde10f402011-04-08 12:57:06 +0200439cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200440{
Victor Stinnerde10f402011-04-08 12:57:06 +0200441 /* notify cancellation */
442 PyThread_release_lock(thread.cancel_event);
443
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200444 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200445 PyThread_acquire_lock(thread.running, 1);
446 PyThread_release_lock(thread.running);
447
448 /* The main thread should always hold the cancel_event lock */
449 PyThread_acquire_lock(thread.cancel_event, 1);
450
Victor Stinner024e37a2011-03-31 01:31:06 +0200451 Py_CLEAR(thread.file);
452}
453
454static PyObject*
Victor Stinner96994402011-04-07 11:37:19 +0200455faulthandler_dump_tracebacks_later(PyObject *self,
456 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200457{
458 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
459 double timeout;
460 PY_TIMEOUT_T timeout_ms;
461 int repeat = 0;
462 PyObject *file = NULL;
463 int fd;
464 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200465 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200466
467 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
468 "d|iOi:dump_tracebacks_later", kwlist,
469 &timeout, &repeat, &file, &exit))
470 return NULL;
471 timeout *= 1e6;
472 if (timeout >= (double) PY_TIMEOUT_MAX) {
473 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
474 return NULL;
475 }
476 timeout_ms = (PY_TIMEOUT_T)timeout;
477 if (timeout_ms <= 0) {
478 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
479 return NULL;
480 }
481
Victor Stinner96994402011-04-07 11:37:19 +0200482 tstate = PyThreadState_Get();
483 if (tstate == NULL) {
484 PyErr_SetString(PyExc_RuntimeError,
485 "unable to get the current thread state");
486 return NULL;
487 }
488
Victor Stinner024e37a2011-03-31 01:31:06 +0200489 file = faulthandler_get_fileno(file, &fd);
490 if (file == NULL)
491 return NULL;
492
493 /* Cancel previous thread, if running */
Victor Stinnerde10f402011-04-08 12:57:06 +0200494 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200495
496 Py_XDECREF(thread.file);
497 Py_INCREF(file);
498 thread.file = file;
499 thread.fd = fd;
500 thread.timeout_ms = timeout_ms;
501 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200502 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200503 thread.exit = exit;
504
505 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200506 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200507
Victor Stinner024e37a2011-03-31 01:31:06 +0200508 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200509 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200510 Py_CLEAR(thread.file);
511 PyErr_SetString(PyExc_RuntimeError,
512 "unable to start watchdog thread");
513 return NULL;
514 }
515
516 Py_RETURN_NONE;
517}
518
519static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200520faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200521{
Victor Stinnerde10f402011-04-08 12:57:06 +0200522 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200523 Py_RETURN_NONE;
524}
525#endif /* FAULTHANDLER_LATER */
526
527#ifdef FAULTHANDLER_USER
528/* Handler of user signals (e.g. SIGUSR1).
529
530 Dump the traceback of the current thread, or of all threads if
531 thread.all_threads is true.
532
533 This function is signal safe and should only call signal safe functions. */
534
535static void
536faulthandler_user(int signum)
537{
538 user_signal_t *user;
539 PyThreadState *tstate;
540
541 user = &user_signals[signum];
542 if (!user->enabled)
543 return;
544
Victor Stinnerff4cd882011-04-07 11:50:25 +0200545#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200546 /* PyThreadState_Get() doesn't give the state of the current thread if
547 the thread doesn't hold the GIL. Read the thread local storage (TLS)
548 instead: call PyGILState_GetThisThreadState(). */
549 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200550#else
551 tstate = PyThreadState_Get();
552#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200553
554 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200555 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
556 else {
557 if (tstate == NULL)
558 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200559 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200560 }
561}
562
563static int
564check_signum(int signum)
565{
566 unsigned int i;
567
568 for (i=0; i < faulthandler_nsignals; i++) {
569 if (faulthandler_handlers[i].signum == signum) {
570 PyErr_Format(PyExc_RuntimeError,
571 "signal %i cannot be registered, "
572 "use enable() instead",
573 signum);
574 return 0;
575 }
576 }
577 if (signum < 1 || NSIG <= signum) {
578 PyErr_SetString(PyExc_ValueError, "signal number out of range");
579 return 0;
580 }
581 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200582}
583
584static PyObject*
585faulthandler_register(PyObject *self,
586 PyObject *args, PyObject *kwargs)
587{
588 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
589 int signum;
590 PyObject *file = NULL;
591 int all_threads = 0;
592 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200593 user_signal_t *user;
594 _Py_sighandler_t previous;
595#ifdef HAVE_SIGACTION
596 struct sigaction action;
597#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200598 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200599 int err;
600
601 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
602 "i|Oi:register", kwlist,
603 &signum, &file, &all_threads))
604 return NULL;
605
Victor Stinner44378d42011-04-01 15:37:12 +0200606 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200607 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200608
Victor Stinner44378d42011-04-01 15:37:12 +0200609 /* The caller holds the GIL and so PyThreadState_Get() can be used */
610 tstate = PyThreadState_Get();
611 if (tstate == NULL) {
612 PyErr_SetString(PyExc_RuntimeError,
613 "unable to get the current thread state");
614 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200615 }
616
617 file = faulthandler_get_fileno(file, &fd);
618 if (file == NULL)
619 return NULL;
620
621 if (user_signals == NULL) {
622 user_signals = calloc(NSIG, sizeof(user_signal_t));
623 if (user_signals == NULL)
624 return PyErr_NoMemory();
625 }
626 user = &user_signals[signum];
627
628 if (!user->enabled) {
629#ifdef HAVE_SIGACTION
630 action.sa_handler = faulthandler_user;
631 sigemptyset(&action.sa_mask);
632 /* if the signal is received while the kernel is executing a system
633 call, try to restart the system call instead of interrupting it and
634 return EINTR */
635 action.sa_flags = SA_RESTART;
636#ifdef HAVE_SIGALTSTACK
637 if (stack.ss_sp != NULL) {
638 /* Call the signal handler on an alternate signal stack
639 provided by sigaltstack() */
640 action.sa_flags |= SA_ONSTACK;
641 }
642#endif
643 err = sigaction(signum, &action, &previous);
644#else
645 previous = signal(signum, faulthandler_user);
646 err = (previous == SIG_ERR);
647#endif
648 if (err) {
649 PyErr_SetFromErrno(PyExc_OSError);
650 return NULL;
651 }
652 }
653
654 Py_XDECREF(user->file);
655 Py_INCREF(file);
656 user->file = file;
657 user->fd = fd;
658 user->all_threads = all_threads;
659 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200660 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200661 user->enabled = 1;
662
663 Py_RETURN_NONE;
664}
665
666static int
667faulthandler_unregister(user_signal_t *user, int signum)
668{
Victor Stinnera01ca122011-04-01 12:56:17 +0200669 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200670 return 0;
671 user->enabled = 0;
672#ifdef HAVE_SIGACTION
673 (void)sigaction(signum, &user->previous, NULL);
674#else
675 (void)signal(signum, user->previous);
676#endif
677 Py_CLEAR(user->file);
678 user->fd = -1;
679 return 1;
680}
681
682static PyObject*
683faulthandler_unregister_py(PyObject *self, PyObject *args)
684{
685 int signum;
686 user_signal_t *user;
687 int change;
688
689 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
690 return NULL;
691
Victor Stinner44378d42011-04-01 15:37:12 +0200692 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200693 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200694
Victor Stinnercfa71232011-04-08 12:48:15 +0200695 if (user_signals == NULL)
696 Py_RETURN_FALSE;
697
Victor Stinner024e37a2011-03-31 01:31:06 +0200698 user = &user_signals[signum];
699 change = faulthandler_unregister(user, signum);
700 return PyBool_FromLong(change);
701}
702#endif /* FAULTHANDLER_USER */
703
704
705static PyObject *
706faulthandler_read_null(PyObject *self, PyObject *args)
707{
708 int *x = NULL, y;
709 int release_gil = 0;
710 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
711 return NULL;
712 if (release_gil) {
713 Py_BEGIN_ALLOW_THREADS
714 y = *x;
715 Py_END_ALLOW_THREADS
716 } else
717 y = *x;
718 return PyLong_FromLong(y);
719
720}
721
722static PyObject *
723faulthandler_sigsegv(PyObject *self, PyObject *args)
724{
725#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200726 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
727 handler and then gives back the execution flow to the program (without
728 calling explicitly the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200729 SIGSEGV was raised by the kernel because of a fault, and so if the
730 program retries to execute the same instruction, the fault will be
731 raised again.
732
733 Here the fault is simulated by a fake SIGSEGV signal raised by the
734 application. We have to raise SIGSEGV at lease twice: once for
735 faulthandler_fatal_error(), and one more time for the previous signal
736 handler. */
737 while(1)
738 raise(SIGSEGV);
739#else
740 raise(SIGSEGV);
741#endif
742 Py_RETURN_NONE;
743}
744
745static PyObject *
746faulthandler_sigfpe(PyObject *self, PyObject *args)
747{
748 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
749 PowerPC. Use volatile to disable compile-time optimizations. */
750 volatile int x = 1, y = 0, z;
751 z = x / y;
752 /* if the division by zero didn't raise a SIGFPE, raise it manually */
753 raise(SIGFPE);
754 Py_RETURN_NONE;
755}
756
Victor Stinnerd727e232011-04-01 12:13:55 +0200757static PyObject *
758faulthandler_sigabrt(PyObject *self, PyObject *args)
759{
760#if _MSC_VER
761 /* If Python is compiled in debug mode with Visual Studio, abort() opens
762 a popup asking the user how to handle the assertion. Use raise(SIGABRT)
763 instead. */
764 raise(SIGABRT);
765#else
766 abort();
767#endif
768 Py_RETURN_NONE;
769}
770
Victor Stinner024e37a2011-03-31 01:31:06 +0200771#ifdef SIGBUS
772static PyObject *
773faulthandler_sigbus(PyObject *self, PyObject *args)
774{
775 raise(SIGBUS);
776 Py_RETURN_NONE;
777}
778#endif
779
780#ifdef SIGILL
781static PyObject *
782faulthandler_sigill(PyObject *self, PyObject *args)
783{
Victor Stinner024e37a2011-03-31 01:31:06 +0200784 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200785 Py_RETURN_NONE;
786}
787#endif
788
789static PyObject *
790faulthandler_fatal_error_py(PyObject *self, PyObject *args)
791{
792 char *message;
793 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
794 return NULL;
795 Py_FatalError(message);
796 Py_RETURN_NONE;
797}
798
799#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200800void*
801stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200802{
803 /* allocate 4096 bytes on the stack at each call */
804 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200805 void *sp = &buffer;
806 *depth += 1;
807 if (sp < min_sp || max_sp < sp)
808 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200809 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200810 buffer[4095] = 0;
811 return stack_overflow(min_sp, max_sp, depth);
812}
813
814static PyObject *
815faulthandler_stack_overflow(PyObject *self)
816{
817 size_t depth, size;
818 void *sp = &depth, *stop;
819
820 depth = 0;
821 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
822 sp + STACK_OVERFLOW_MAX_SIZE,
823 &depth);
824 if (sp < stop)
825 size = stop - sp;
826 else
827 size = sp - stop;
828 PyErr_Format(PyExc_RuntimeError,
829 "unable to raise a stack overflow (allocated %zu bytes "
830 "on the stack, %zu recursive calls)",
831 size, depth);
832 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200833}
834#endif
835
836
837static int
838faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
839{
840#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200841 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200842#endif
843
844#ifdef FAULTHANDLER_LATER
845 Py_VISIT(thread.file);
846#endif
847#ifdef FAULTHANDLER_USER
848 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200849 for (signum=0; signum < NSIG; signum++)
850 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200851 }
852#endif
853 Py_VISIT(fatal_error.file);
854 return 0;
855}
856
857PyDoc_STRVAR(module_doc,
858"faulthandler module.");
859
860static PyMethodDef module_methods[] = {
861 {"enable",
862 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
863 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
864 "enable the fault handler")},
865 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
866 PyDoc_STR("disable(): disable the fault handler")},
867 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
868 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
869 {"dump_traceback",
870 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
871 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
872 "dump the traceback of the current thread, or of all threads "
873 "if all_threads is True, into file")},
874#ifdef FAULTHANDLER_LATER
875 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +0200876 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
877 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200878 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200879 "or each timeout seconds if repeat is True. If exit is True, "
880 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200881 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200882 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200883 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
884 "to dump_tracebacks_later().")},
885#endif
886
887#ifdef FAULTHANDLER_USER
888 {"register",
889 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
890 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
891 "register an handler for the signal 'signum': dump the "
892 "traceback of the current thread, or of all threads if "
893 "all_threads is True, into file")},
894 {"unregister",
895 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
896 PyDoc_STR("unregister(signum): unregister the handler of the signal "
897 "'signum' registered by register()")},
898#endif
899
900 {"_read_null", faulthandler_read_null, METH_VARARGS,
901 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
902 "a SIGSEGV or SIGBUS signal depending on the platform")},
903 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
904 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200905 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
906 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200907 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
908 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
909#ifdef SIGBUS
910 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
911 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
912#endif
913#ifdef SIGILL
914 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
915 PyDoc_STR("_sigill(): raise a SIGILL signal")},
916#endif
917 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
918 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
919#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
920 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
921 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
922#endif
923 {NULL, NULL} /* terminator */
924};
925
926static struct PyModuleDef module_def = {
927 PyModuleDef_HEAD_INIT,
928 "faulthandler",
929 module_doc,
930 0, /* non negative size to be able to unload the module */
931 module_methods,
932 NULL,
933 faulthandler_traverse,
934 NULL,
935 NULL
936};
937
938PyMODINIT_FUNC
939PyInit_faulthandler(void)
940{
941 return PyModule_Create(&module_def);
942}
943
944/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
945 defined, or if sys._xoptions has a 'faulthandler' key. */
946
947static int
948faulthandler_env_options(void)
949{
950 PyObject *xoptions, *key, *module, *res;
951 int enable;
952
953 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
954 xoptions = PySys_GetXOptions();
955 if (xoptions == NULL)
956 return -1;
957
958 key = PyUnicode_FromString("faulthandler");
959 if (key == NULL)
960 return -1;
961
962 enable = PyDict_Contains(xoptions, key);
963 Py_DECREF(key);
964 if (!enable)
965 return 0;
966 }
967 else
968 enable = 1;
969
970 module = PyImport_ImportModule("faulthandler");
971 if (module == NULL) {
972 return -1;
973 }
974 res = PyObject_CallMethod(module, "enable", "");
975 Py_DECREF(module);
976 if (res == NULL)
977 return -1;
978 Py_DECREF(res);
979 return 0;
980}
981
982int _PyFaulthandler_Init(void)
983{
984#ifdef HAVE_SIGALTSTACK
985 int err;
986
987 /* Try to allocate an alternate stack for faulthandler() signal handler to
988 * be able to allocate memory on the stack, even on a stack overflow. If it
989 * fails, ignore the error. */
990 stack.ss_flags = 0;
991 stack.ss_size = SIGSTKSZ;
992 stack.ss_sp = PyMem_Malloc(stack.ss_size);
993 if (stack.ss_sp != NULL) {
994 err = sigaltstack(&stack, NULL);
995 if (err) {
996 PyMem_Free(stack.ss_sp);
997 stack.ss_sp = NULL;
998 }
999 }
1000#endif
1001#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001002 thread.file = NULL;
1003 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001004 thread.running = PyThread_allocate_lock();
1005 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001006 PyErr_SetString(PyExc_RuntimeError,
1007 "could not allocate locks for faulthandler");
1008 return -1;
1009 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001010 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001011#endif
1012
1013 return faulthandler_env_options();
1014}
1015
1016void _PyFaulthandler_Fini(void)
1017{
1018#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001019 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001020#endif
1021
1022#ifdef FAULTHANDLER_LATER
1023 /* later */
Victor Stinnerde10f402011-04-08 12:57:06 +02001024 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001025 if (thread.cancel_event) {
Victor Stinnerde10f402011-04-08 12:57:06 +02001026 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001027 PyThread_free_lock(thread.cancel_event);
1028 thread.cancel_event = NULL;
1029 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001030 if (thread.running) {
1031 PyThread_free_lock(thread.running);
1032 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001033 }
1034#endif
1035
1036#ifdef FAULTHANDLER_USER
1037 /* user */
1038 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001039 for (signum=0; signum < NSIG; signum++)
1040 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001041 free(user_signals);
1042 user_signals = NULL;
1043 }
1044#endif
1045
1046 /* fatal */
1047 faulthandler_disable();
1048#ifdef HAVE_SIGALTSTACK
1049 if (stack.ss_sp != NULL) {
1050 PyMem_Free(stack.ss_sp);
1051 stack.ss_sp = NULL;
1052 }
1053#endif
1054}