blob: 2b353997601c9d5a0b170afa13b81990eed1793d [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;
Victor Stinner94189322011-04-08 13:00:31 +020049 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020050 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020051 PyInterpreterState *interp;
52 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020053 char *header;
54 size_t header_len;
Victor Stinnerde10f402011-04-08 12:57:06 +020055 /* The main thread always hold this lock. It is only released when
56 faulthandler_thread() is interrupted until this thread exits, or at
57 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020058 PyThread_type_lock cancel_event;
59 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020060 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020061} thread;
62#endif
63
64#ifdef FAULTHANDLER_USER
65typedef struct {
66 int enabled;
67 PyObject *file;
68 int fd;
69 int all_threads;
70 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020071 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020072} user_signal_t;
73
74static user_signal_t *user_signals;
75
76/* the following macros come from Python: Modules/signalmodule.c */
77#if defined(PYOS_OS2) && !defined(PYCC_GCC)
78#define NSIG 12
79#endif
80#ifndef NSIG
81# if defined(_NSIG)
82# define NSIG _NSIG /* For BSD/SysV */
83# elif defined(_SIGMAX)
84# define NSIG (_SIGMAX + 1) /* For QNX */
85# elif defined(SIGMAX)
86# define NSIG (SIGMAX + 1) /* For djgpp */
87# else
88# define NSIG 64 /* Use a reasonable default value */
89# endif
90#endif
91
92#endif /* FAULTHANDLER_USER */
93
94
95static fault_handler_t faulthandler_handlers[] = {
96#ifdef SIGBUS
97 {SIGBUS, 0, "Bus error", },
98#endif
99#ifdef SIGILL
100 {SIGILL, 0, "Illegal instruction", },
101#endif
102 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200103 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200104 /* define SIGSEGV at the end to make it the default choice if searching the
105 handler fails in faulthandler_fatal_error() */
106 {SIGSEGV, 0, "Segmentation fault", }
107};
108static const unsigned char faulthandler_nsignals = \
109 sizeof(faulthandler_handlers) / sizeof(faulthandler_handlers[0]);
110
111#ifdef HAVE_SIGALTSTACK
112static stack_t stack;
113#endif
114
115
116/* Get the file descriptor of a file by calling its fileno() method and then
117 call its flush() method.
118
119 If file is NULL or Py_None, use sys.stderr as the new file.
120
121 On success, return the new file and write the file descriptor into *p_fd.
122 On error, return NULL. */
123
124static PyObject*
125faulthandler_get_fileno(PyObject *file, int *p_fd)
126{
127 PyObject *result;
128 long fd_long;
129 int fd;
130
131 if (file == NULL || file == Py_None) {
132 file = PySys_GetObject("stderr");
133 if (file == NULL) {
134 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
135 return NULL;
136 }
137 }
138
139 result = PyObject_CallMethod(file, "fileno", "");
140 if (result == NULL)
141 return NULL;
142
143 fd = -1;
144 if (PyLong_Check(result)) {
145 fd_long = PyLong_AsLong(result);
146 if (0 <= fd_long && fd_long < INT_MAX)
147 fd = (int)fd_long;
148 }
149 Py_DECREF(result);
150
151 if (fd == -1) {
152 PyErr_SetString(PyExc_RuntimeError,
153 "file.fileno() is not a valid file descriptor");
154 return NULL;
155 }
156
157 result = PyObject_CallMethod(file, "flush", "");
158 if (result != NULL)
159 Py_DECREF(result);
160 else {
161 /* ignore flush() error */
162 PyErr_Clear();
163 }
164 *p_fd = fd;
165 return file;
166}
167
168static PyObject*
169faulthandler_dump_traceback_py(PyObject *self,
170 PyObject *args, PyObject *kwargs)
171{
172 static char *kwlist[] = {"file", "all_threads", NULL};
173 PyObject *file = NULL;
174 int all_threads = 0;
175 PyThreadState *tstate;
176 const char *errmsg;
177 int fd;
178
179 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
180 "|Oi:dump_traceback", kwlist,
181 &file, &all_threads))
182 return NULL;
183
184 file = faulthandler_get_fileno(file, &fd);
185 if (file == NULL)
186 return NULL;
187
188 /* The caller holds the GIL and so PyThreadState_Get() can be used */
189 tstate = PyThreadState_Get();
190 if (tstate == NULL) {
191 PyErr_SetString(PyExc_RuntimeError,
192 "unable to get the current thread state");
193 return NULL;
194 }
195
196 if (all_threads) {
197 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
198 if (errmsg != NULL) {
199 PyErr_SetString(PyExc_RuntimeError, errmsg);
200 return NULL;
201 }
202 }
203 else {
204 _Py_DumpTraceback(fd, tstate);
205 }
206 Py_RETURN_NONE;
207}
208
209
Victor Stinnerd727e232011-04-01 12:13:55 +0200210/* Handler of SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200211
212 Display the current Python traceback, restore the previous handler and call
213 the previous handler.
214
215 On Windows, don't call explictly the previous handler, because Windows
216 signal handler would not be called (for an unknown reason). The execution of
217 the program continues at faulthandler_fatal_error() exit, but the same
218 instruction will raise the same fault (signal), and so the previous handler
219 will be called.
220
221 This function is signal safe and should only call signal safe functions. */
222
223static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200224faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200225{
226 const int fd = fatal_error.fd;
227 unsigned int i;
228 fault_handler_t *handler = NULL;
229 PyThreadState *tstate;
230
231 if (!fatal_error.enabled)
232 return;
233
234 for (i=0; i < faulthandler_nsignals; i++) {
235 handler = &faulthandler_handlers[i];
236 if (handler->signum == signum)
237 break;
238 }
239 if (handler == NULL) {
240 /* faulthandler_nsignals == 0 (unlikely) */
241 return;
242 }
243
244 /* restore the previous handler */
245#ifdef HAVE_SIGACTION
246 (void)sigaction(handler->signum, &handler->previous, NULL);
247#else
248 (void)signal(handler->signum, handler->previous);
249#endif
250 handler->enabled = 0;
251
252 PUTS(fd, "Fatal Python error: ");
253 PUTS(fd, handler->name);
254 PUTS(fd, "\n\n");
255
Victor Stinnerff4cd882011-04-07 11:50:25 +0200256#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200257 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
258 so are delivered to the thread that caused the fault. Get the Python
259 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200260
261 PyThreadState_Get() doesn't give the state of the thread that caused the
262 fault if the thread released the GIL, and so this function cannot be
263 used. Read the thread local storage (TLS) instead: call
264 PyGILState_GetThisThreadState(). */
265 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200266#else
267 tstate = PyThreadState_Get();
268#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200269 if (tstate == NULL)
270 return;
271
272 if (fatal_error.all_threads)
273 _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
274 else
275 _Py_DumpTraceback(fd, tstate);
276
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200277#ifdef MS_WINDOWS
278 if (signum == SIGSEGV) {
279 /* don't call explictly the previous handler for SIGSEGV in this signal
280 handler, because the Windows signal handler would not be called */
281 return;
282 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200283#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200284 /* call the previous signal handler: it is called immediatly if we use
285 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
286 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200287}
288
Victor Stinnerd727e232011-04-01 12:13:55 +0200289/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200290
291static PyObject*
292faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
293{
294 static char *kwlist[] = {"file", "all_threads", NULL};
295 PyObject *file = NULL;
296 int all_threads = 0;
297 unsigned int i;
298 fault_handler_t *handler;
299#ifdef HAVE_SIGACTION
300 struct sigaction action;
301#endif
302 int err;
303 int fd;
304
305 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
306 "|Oi:enable", kwlist, &file, &all_threads))
307 return NULL;
308
309 file = faulthandler_get_fileno(file, &fd);
310 if (file == NULL)
311 return NULL;
312
313 Py_XDECREF(fatal_error.file);
314 Py_INCREF(file);
315 fatal_error.file = file;
316 fatal_error.fd = fd;
317 fatal_error.all_threads = all_threads;
318
319 if (!fatal_error.enabled) {
320 fatal_error.enabled = 1;
321
322 for (i=0; i < faulthandler_nsignals; i++) {
323 handler = &faulthandler_handlers[i];
324#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200325 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200326 sigemptyset(&action.sa_mask);
327 /* Do not prevent the signal from being received from within
328 its own signal handler */
329 action.sa_flags = SA_NODEFER;
330#ifdef HAVE_SIGALTSTACK
331 if (stack.ss_sp != NULL) {
332 /* Call the signal handler on an alternate signal stack
333 provided by sigaltstack() */
334 action.sa_flags |= SA_ONSTACK;
335 }
336#endif
337 err = sigaction(handler->signum, &action, &handler->previous);
338#else
339 handler->previous = signal(handler->signum,
340 faulthandler_fatal_error);
341 err = (handler->previous == SIG_ERR);
342#endif
343 if (err) {
344 PyErr_SetFromErrno(PyExc_RuntimeError);
345 return NULL;
346 }
347 handler->enabled = 1;
348 }
349 }
350 Py_RETURN_NONE;
351}
352
353static void
354faulthandler_disable(void)
355{
356 unsigned int i;
357 fault_handler_t *handler;
358
359 if (fatal_error.enabled) {
360 fatal_error.enabled = 0;
361 for (i=0; i < faulthandler_nsignals; i++) {
362 handler = &faulthandler_handlers[i];
363 if (!handler->enabled)
364 continue;
365#ifdef HAVE_SIGACTION
366 (void)sigaction(handler->signum, &handler->previous, NULL);
367#else
368 (void)signal(handler->signum, handler->previous);
369#endif
370 handler->enabled = 0;
371 }
372 }
373
374 Py_CLEAR(fatal_error.file);
375}
376
377static PyObject*
378faulthandler_disable_py(PyObject *self)
379{
380 if (!fatal_error.enabled) {
381 Py_INCREF(Py_False);
382 return Py_False;
383 }
384 faulthandler_disable();
385 Py_INCREF(Py_True);
386 return Py_True;
387}
388
389static PyObject*
390faulthandler_is_enabled(PyObject *self)
391{
392 return PyBool_FromLong(fatal_error.enabled);
393}
394
395#ifdef FAULTHANDLER_LATER
396
397static void
398faulthandler_thread(void *unused)
399{
400 PyLockStatus st;
401 const char* errmsg;
402 PyThreadState *current;
403 int ok;
Victor Stinnerda9edae2011-04-04 11:05:21 +0200404#ifdef HAVE_PTHREAD_H
405 sigset_t set;
406
407 /* we don't want to receive any signal */
408 sigfillset(&set);
409#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
410 pthread_sigmask(SIG_SETMASK, &set, NULL);
411#else
412 sigprocmask(SIG_SETMASK, &set, NULL);
413#endif
414#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200415
416 do {
417 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200418 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200419 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200420 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200421 break;
422 }
423 /* Timeout => dump traceback */
424 assert(st == PY_LOCK_FAILURE);
425
426 /* get the thread holding the GIL, NULL if no thread hold the GIL */
427 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
428
Victor Stinnerc790a532011-04-08 13:39:59 +0200429 write(thread.fd, thread.header, thread.header_len);
430
Victor Stinner024e37a2011-03-31 01:31:06 +0200431 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
432 ok = (errmsg == NULL);
433
434 if (thread.exit)
435 _exit(1);
436 } while (ok && thread.repeat);
437
438 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200439 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200440}
441
442static void
Victor Stinnerde10f402011-04-08 12:57:06 +0200443cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200444{
Victor Stinnerde10f402011-04-08 12:57:06 +0200445 /* notify cancellation */
446 PyThread_release_lock(thread.cancel_event);
447
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200448 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200449 PyThread_acquire_lock(thread.running, 1);
450 PyThread_release_lock(thread.running);
451
452 /* The main thread should always hold the cancel_event lock */
453 PyThread_acquire_lock(thread.cancel_event, 1);
454
Victor Stinner024e37a2011-03-31 01:31:06 +0200455 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200456 if (thread.header) {
457 free(thread.header);
458 thread.header = NULL;
459 }
460}
461
462static char*
463format_timeout(double timeout)
464{
465 unsigned long us, sec, min, hour;
466 double intpart, fracpart;
467 char buffer[100];
468
469 fracpart = modf(timeout, &intpart);
470 sec = (unsigned long)intpart;
471 us = (unsigned long)(fracpart * 1e6);
472 min = sec / 60;
473 sec %= 60;
474 hour = min / 60;
475 min %= 60;
476
477 if (us != 0)
478 PyOS_snprintf(buffer, sizeof(buffer),
479 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
480 hour, min, sec, us);
481 else
482 PyOS_snprintf(buffer, sizeof(buffer),
483 "Timeout (%lu:%02lu:%02lu)!\n",
484 hour, min, sec);
485
486 return strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200487}
488
489static PyObject*
Victor Stinner96994402011-04-07 11:37:19 +0200490faulthandler_dump_tracebacks_later(PyObject *self,
491 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200492{
493 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
494 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200495 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200496 int repeat = 0;
497 PyObject *file = NULL;
498 int fd;
499 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200500 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200501 char *header;
502 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200503
504 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
505 "d|iOi:dump_tracebacks_later", kwlist,
506 &timeout, &repeat, &file, &exit))
507 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200508 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200509 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
510 return NULL;
511 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200512 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200513 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200514 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
515 return NULL;
516 }
517
Victor Stinner96994402011-04-07 11:37:19 +0200518 tstate = PyThreadState_Get();
519 if (tstate == NULL) {
520 PyErr_SetString(PyExc_RuntimeError,
521 "unable to get the current thread state");
522 return NULL;
523 }
524
Victor Stinner024e37a2011-03-31 01:31:06 +0200525 file = faulthandler_get_fileno(file, &fd);
526 if (file == NULL)
527 return NULL;
528
Victor Stinnerc790a532011-04-08 13:39:59 +0200529 /* format the timeout */
530 header = format_timeout(timeout);
531 if (header == NULL)
532 return PyErr_NoMemory();
533 header_len = strlen(header);
534
Victor Stinner024e37a2011-03-31 01:31:06 +0200535 /* Cancel previous thread, if running */
Victor Stinnerde10f402011-04-08 12:57:06 +0200536 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200537
538 Py_XDECREF(thread.file);
539 Py_INCREF(file);
540 thread.file = file;
541 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200542 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200543 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200544 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200545 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200546 thread.header = header;
547 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200548
549 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200550 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200551
Victor Stinner024e37a2011-03-31 01:31:06 +0200552 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200553 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200554 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200555 free(header);
556 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200557 PyErr_SetString(PyExc_RuntimeError,
558 "unable to start watchdog thread");
559 return NULL;
560 }
561
562 Py_RETURN_NONE;
563}
564
565static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200566faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200567{
Victor Stinnerde10f402011-04-08 12:57:06 +0200568 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200569 Py_RETURN_NONE;
570}
571#endif /* FAULTHANDLER_LATER */
572
573#ifdef FAULTHANDLER_USER
574/* Handler of user signals (e.g. SIGUSR1).
575
576 Dump the traceback of the current thread, or of all threads if
577 thread.all_threads is true.
578
579 This function is signal safe and should only call signal safe functions. */
580
581static void
582faulthandler_user(int signum)
583{
584 user_signal_t *user;
585 PyThreadState *tstate;
586
587 user = &user_signals[signum];
588 if (!user->enabled)
589 return;
590
Victor Stinnerff4cd882011-04-07 11:50:25 +0200591#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200592 /* PyThreadState_Get() doesn't give the state of the current thread if
593 the thread doesn't hold the GIL. Read the thread local storage (TLS)
594 instead: call PyGILState_GetThisThreadState(). */
595 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200596#else
597 tstate = PyThreadState_Get();
598#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200599
600 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200601 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
602 else {
603 if (tstate == NULL)
604 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200605 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200606 }
607}
608
609static int
610check_signum(int signum)
611{
612 unsigned int i;
613
614 for (i=0; i < faulthandler_nsignals; i++) {
615 if (faulthandler_handlers[i].signum == signum) {
616 PyErr_Format(PyExc_RuntimeError,
617 "signal %i cannot be registered, "
618 "use enable() instead",
619 signum);
620 return 0;
621 }
622 }
623 if (signum < 1 || NSIG <= signum) {
624 PyErr_SetString(PyExc_ValueError, "signal number out of range");
625 return 0;
626 }
627 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200628}
629
630static PyObject*
631faulthandler_register(PyObject *self,
632 PyObject *args, PyObject *kwargs)
633{
634 static char *kwlist[] = {"signum", "file", "all_threads", NULL};
635 int signum;
636 PyObject *file = NULL;
637 int all_threads = 0;
638 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200639 user_signal_t *user;
640 _Py_sighandler_t previous;
641#ifdef HAVE_SIGACTION
642 struct sigaction action;
643#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200644 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200645 int err;
646
647 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
648 "i|Oi:register", kwlist,
649 &signum, &file, &all_threads))
650 return NULL;
651
Victor Stinner44378d42011-04-01 15:37:12 +0200652 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200653 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200654
Victor Stinner44378d42011-04-01 15:37:12 +0200655 /* The caller holds the GIL and so PyThreadState_Get() can be used */
656 tstate = PyThreadState_Get();
657 if (tstate == NULL) {
658 PyErr_SetString(PyExc_RuntimeError,
659 "unable to get the current thread state");
660 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200661 }
662
663 file = faulthandler_get_fileno(file, &fd);
664 if (file == NULL)
665 return NULL;
666
667 if (user_signals == NULL) {
668 user_signals = calloc(NSIG, sizeof(user_signal_t));
669 if (user_signals == NULL)
670 return PyErr_NoMemory();
671 }
672 user = &user_signals[signum];
673
674 if (!user->enabled) {
675#ifdef HAVE_SIGACTION
676 action.sa_handler = faulthandler_user;
677 sigemptyset(&action.sa_mask);
678 /* if the signal is received while the kernel is executing a system
679 call, try to restart the system call instead of interrupting it and
680 return EINTR */
681 action.sa_flags = SA_RESTART;
682#ifdef HAVE_SIGALTSTACK
683 if (stack.ss_sp != NULL) {
684 /* Call the signal handler on an alternate signal stack
685 provided by sigaltstack() */
686 action.sa_flags |= SA_ONSTACK;
687 }
688#endif
689 err = sigaction(signum, &action, &previous);
690#else
691 previous = signal(signum, faulthandler_user);
692 err = (previous == SIG_ERR);
693#endif
694 if (err) {
695 PyErr_SetFromErrno(PyExc_OSError);
696 return NULL;
697 }
698 }
699
700 Py_XDECREF(user->file);
701 Py_INCREF(file);
702 user->file = file;
703 user->fd = fd;
704 user->all_threads = all_threads;
705 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200706 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200707 user->enabled = 1;
708
709 Py_RETURN_NONE;
710}
711
712static int
713faulthandler_unregister(user_signal_t *user, int signum)
714{
Victor Stinnera01ca122011-04-01 12:56:17 +0200715 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200716 return 0;
717 user->enabled = 0;
718#ifdef HAVE_SIGACTION
719 (void)sigaction(signum, &user->previous, NULL);
720#else
721 (void)signal(signum, user->previous);
722#endif
723 Py_CLEAR(user->file);
724 user->fd = -1;
725 return 1;
726}
727
728static PyObject*
729faulthandler_unregister_py(PyObject *self, PyObject *args)
730{
731 int signum;
732 user_signal_t *user;
733 int change;
734
735 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
736 return NULL;
737
Victor Stinner44378d42011-04-01 15:37:12 +0200738 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200739 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200740
Victor Stinnercfa71232011-04-08 12:48:15 +0200741 if (user_signals == NULL)
742 Py_RETURN_FALSE;
743
Victor Stinner024e37a2011-03-31 01:31:06 +0200744 user = &user_signals[signum];
745 change = faulthandler_unregister(user, signum);
746 return PyBool_FromLong(change);
747}
748#endif /* FAULTHANDLER_USER */
749
750
751static PyObject *
752faulthandler_read_null(PyObject *self, PyObject *args)
753{
754 int *x = NULL, y;
755 int release_gil = 0;
756 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
757 return NULL;
758 if (release_gil) {
759 Py_BEGIN_ALLOW_THREADS
760 y = *x;
761 Py_END_ALLOW_THREADS
762 } else
763 y = *x;
764 return PyLong_FromLong(y);
765
766}
767
768static PyObject *
769faulthandler_sigsegv(PyObject *self, PyObject *args)
770{
771#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200772 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
773 handler and then gives back the execution flow to the program (without
774 calling explicitly the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200775 SIGSEGV was raised by the kernel because of a fault, and so if the
776 program retries to execute the same instruction, the fault will be
777 raised again.
778
779 Here the fault is simulated by a fake SIGSEGV signal raised by the
780 application. We have to raise SIGSEGV at lease twice: once for
781 faulthandler_fatal_error(), and one more time for the previous signal
782 handler. */
783 while(1)
784 raise(SIGSEGV);
785#else
786 raise(SIGSEGV);
787#endif
788 Py_RETURN_NONE;
789}
790
791static PyObject *
792faulthandler_sigfpe(PyObject *self, PyObject *args)
793{
794 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
795 PowerPC. Use volatile to disable compile-time optimizations. */
796 volatile int x = 1, y = 0, z;
797 z = x / y;
798 /* if the division by zero didn't raise a SIGFPE, raise it manually */
799 raise(SIGFPE);
800 Py_RETURN_NONE;
801}
802
Victor Stinnerd727e232011-04-01 12:13:55 +0200803static PyObject *
804faulthandler_sigabrt(PyObject *self, PyObject *args)
805{
806#if _MSC_VER
807 /* If Python is compiled in debug mode with Visual Studio, abort() opens
808 a popup asking the user how to handle the assertion. Use raise(SIGABRT)
809 instead. */
810 raise(SIGABRT);
811#else
812 abort();
813#endif
814 Py_RETURN_NONE;
815}
816
Victor Stinner024e37a2011-03-31 01:31:06 +0200817#ifdef SIGBUS
818static PyObject *
819faulthandler_sigbus(PyObject *self, PyObject *args)
820{
821 raise(SIGBUS);
822 Py_RETURN_NONE;
823}
824#endif
825
826#ifdef SIGILL
827static PyObject *
828faulthandler_sigill(PyObject *self, PyObject *args)
829{
Victor Stinner024e37a2011-03-31 01:31:06 +0200830 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200831 Py_RETURN_NONE;
832}
833#endif
834
835static PyObject *
836faulthandler_fatal_error_py(PyObject *self, PyObject *args)
837{
838 char *message;
839 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
840 return NULL;
841 Py_FatalError(message);
842 Py_RETURN_NONE;
843}
844
845#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinnerf0480752011-03-31 11:34:08 +0200846void*
847stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200848{
849 /* allocate 4096 bytes on the stack at each call */
850 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200851 void *sp = &buffer;
852 *depth += 1;
853 if (sp < min_sp || max_sp < sp)
854 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200855 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200856 buffer[4095] = 0;
857 return stack_overflow(min_sp, max_sp, depth);
858}
859
860static PyObject *
861faulthandler_stack_overflow(PyObject *self)
862{
863 size_t depth, size;
864 void *sp = &depth, *stop;
865
866 depth = 0;
867 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
868 sp + STACK_OVERFLOW_MAX_SIZE,
869 &depth);
870 if (sp < stop)
871 size = stop - sp;
872 else
873 size = sp - stop;
874 PyErr_Format(PyExc_RuntimeError,
875 "unable to raise a stack overflow (allocated %zu bytes "
876 "on the stack, %zu recursive calls)",
877 size, depth);
878 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200879}
880#endif
881
882
883static int
884faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
885{
886#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200887 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200888#endif
889
890#ifdef FAULTHANDLER_LATER
891 Py_VISIT(thread.file);
892#endif
893#ifdef FAULTHANDLER_USER
894 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200895 for (signum=0; signum < NSIG; signum++)
896 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200897 }
898#endif
899 Py_VISIT(fatal_error.file);
900 return 0;
901}
902
903PyDoc_STRVAR(module_doc,
904"faulthandler module.");
905
906static PyMethodDef module_methods[] = {
907 {"enable",
908 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
909 PyDoc_STR("enable(file=sys.stderr, all_threads=False): "
910 "enable the fault handler")},
911 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
912 PyDoc_STR("disable(): disable the fault handler")},
913 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
914 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
915 {"dump_traceback",
916 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
917 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=False): "
918 "dump the traceback of the current thread, or of all threads "
919 "if all_threads is True, into file")},
920#ifdef FAULTHANDLER_LATER
921 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +0200922 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
923 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200924 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200925 "or each timeout seconds if repeat is True. If exit is True, "
926 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200927 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200928 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200929 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
930 "to dump_tracebacks_later().")},
931#endif
932
933#ifdef FAULTHANDLER_USER
934 {"register",
935 (PyCFunction)faulthandler_register, METH_VARARGS|METH_KEYWORDS,
936 PyDoc_STR("register(signum, file=sys.stderr, all_threads=False): "
937 "register an handler for the signal 'signum': dump the "
938 "traceback of the current thread, or of all threads if "
939 "all_threads is True, into file")},
940 {"unregister",
941 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
942 PyDoc_STR("unregister(signum): unregister the handler of the signal "
943 "'signum' registered by register()")},
944#endif
945
946 {"_read_null", faulthandler_read_null, METH_VARARGS,
947 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
948 "a SIGSEGV or SIGBUS signal depending on the platform")},
949 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
950 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200951 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
952 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200953 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
954 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
955#ifdef SIGBUS
956 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
957 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
958#endif
959#ifdef SIGILL
960 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
961 PyDoc_STR("_sigill(): raise a SIGILL signal")},
962#endif
963 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
964 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
965#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
966 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
967 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
968#endif
969 {NULL, NULL} /* terminator */
970};
971
972static struct PyModuleDef module_def = {
973 PyModuleDef_HEAD_INIT,
974 "faulthandler",
975 module_doc,
976 0, /* non negative size to be able to unload the module */
977 module_methods,
978 NULL,
979 faulthandler_traverse,
980 NULL,
981 NULL
982};
983
984PyMODINIT_FUNC
985PyInit_faulthandler(void)
986{
987 return PyModule_Create(&module_def);
988}
989
990/* Call faulthandler.enable() if PYTHONFAULTHANDLER environment variable is
991 defined, or if sys._xoptions has a 'faulthandler' key. */
992
993static int
994faulthandler_env_options(void)
995{
996 PyObject *xoptions, *key, *module, *res;
997 int enable;
998
999 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
1000 xoptions = PySys_GetXOptions();
1001 if (xoptions == NULL)
1002 return -1;
1003
1004 key = PyUnicode_FromString("faulthandler");
1005 if (key == NULL)
1006 return -1;
1007
1008 enable = PyDict_Contains(xoptions, key);
1009 Py_DECREF(key);
1010 if (!enable)
1011 return 0;
1012 }
1013 else
1014 enable = 1;
1015
1016 module = PyImport_ImportModule("faulthandler");
1017 if (module == NULL) {
1018 return -1;
1019 }
1020 res = PyObject_CallMethod(module, "enable", "");
1021 Py_DECREF(module);
1022 if (res == NULL)
1023 return -1;
1024 Py_DECREF(res);
1025 return 0;
1026}
1027
1028int _PyFaulthandler_Init(void)
1029{
1030#ifdef HAVE_SIGALTSTACK
1031 int err;
1032
1033 /* Try to allocate an alternate stack for faulthandler() signal handler to
1034 * be able to allocate memory on the stack, even on a stack overflow. If it
1035 * fails, ignore the error. */
1036 stack.ss_flags = 0;
1037 stack.ss_size = SIGSTKSZ;
1038 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1039 if (stack.ss_sp != NULL) {
1040 err = sigaltstack(&stack, NULL);
1041 if (err) {
1042 PyMem_Free(stack.ss_sp);
1043 stack.ss_sp = NULL;
1044 }
1045 }
1046#endif
1047#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001048 thread.file = NULL;
1049 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001050 thread.running = PyThread_allocate_lock();
1051 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001052 PyErr_SetString(PyExc_RuntimeError,
1053 "could not allocate locks for faulthandler");
1054 return -1;
1055 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001056 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001057#endif
1058
1059 return faulthandler_env_options();
1060}
1061
1062void _PyFaulthandler_Fini(void)
1063{
1064#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001065 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001066#endif
1067
1068#ifdef FAULTHANDLER_LATER
1069 /* later */
Victor Stinnerde10f402011-04-08 12:57:06 +02001070 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001071 if (thread.cancel_event) {
Victor Stinnerde10f402011-04-08 12:57:06 +02001072 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001073 PyThread_free_lock(thread.cancel_event);
1074 thread.cancel_event = NULL;
1075 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001076 if (thread.running) {
1077 PyThread_free_lock(thread.running);
1078 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001079 }
1080#endif
1081
1082#ifdef FAULTHANDLER_USER
1083 /* user */
1084 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001085 for (signum=0; signum < NSIG; signum++)
1086 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001087 free(user_signals);
1088 user_signals = NULL;
1089 }
1090#endif
1091
1092 /* fatal */
1093 faulthandler_disable();
1094#ifdef HAVE_SIGALTSTACK
1095 if (stack.ss_sp != NULL) {
1096 PyMem_Free(stack.ss_sp);
1097 stack.ss_sp = NULL;
1098 }
1099#endif
1100}