blob: 3002840f64dda2e754e33fcc533710aa78b9c901 [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>
Victor Stinner0aafa4f2011-06-29 23:28:02 +02007#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
8#include <pthread.h>
9#endif
10
Victor Stinner96994402011-04-07 11:37:19 +020011/* Allocate at maximum 100 MB of the stack to raise the stack overflow */
12#define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
13
Victor Stinner024e37a2011-03-31 01:31:06 +020014#ifdef WITH_THREAD
15# define FAULTHANDLER_LATER
Antoine Pitrou75e78b62011-10-04 11:51:23 +020016# define FAULTHANDLER_WATCHDOG
Victor Stinner024e37a2011-03-31 01:31:06 +020017#endif
18
19#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020020 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
21 SIGILL can be handled by the process, and these signals can only be used
22 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020023# define FAULTHANDLER_USER
24#endif
25
26#define PUTS(fd, str) write(fd, str, strlen(str))
27
28#ifdef HAVE_SIGACTION
29typedef struct sigaction _Py_sighandler_t;
30#else
31typedef PyOS_sighandler_t _Py_sighandler_t;
32#endif
33
34typedef struct {
35 int signum;
36 int enabled;
37 const char* name;
38 _Py_sighandler_t previous;
39 int all_threads;
40} fault_handler_t;
41
42static struct {
43 int enabled;
44 PyObject *file;
45 int fd;
46 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020047 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020048} fatal_error = {0, NULL, -1, 0};
49
50#ifdef FAULTHANDLER_LATER
51static struct {
52 PyObject *file;
53 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020054 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020055 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020056 PyInterpreterState *interp;
57 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020058 char *header;
59 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020060 /* The main thread always holds this lock. It is only released when
61 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020062 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020063 PyThread_type_lock cancel_event;
64 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020065 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020066} thread;
67#endif
68
Antoine Pitrou75e78b62011-10-04 11:51:23 +020069#ifdef FAULTHANDLER_WATCHDOG
70static struct {
71 int rfd;
72 int wfd;
73 PY_TIMEOUT_T period_us; /* period in microseconds */
74 /* The main thread always holds this lock. It is only released when
75 faulthandler_watchdog() is interrupted before this thread exits, or at
76 Python exit. */
77 PyThread_type_lock cancel_event;
78 /* released by child thread when joined */
79 PyThread_type_lock running;
80} watchdog;
81#endif
82
Victor Stinner024e37a2011-03-31 01:31:06 +020083#ifdef FAULTHANDLER_USER
84typedef struct {
85 int enabled;
86 PyObject *file;
87 int fd;
88 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020089 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020090 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020091 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020092} user_signal_t;
93
94static user_signal_t *user_signals;
95
96/* the following macros come from Python: Modules/signalmodule.c */
97#if defined(PYOS_OS2) && !defined(PYCC_GCC)
98#define NSIG 12
99#endif
100#ifndef NSIG
101# if defined(_NSIG)
102# define NSIG _NSIG /* For BSD/SysV */
103# elif defined(_SIGMAX)
104# define NSIG (_SIGMAX + 1) /* For QNX */
105# elif defined(SIGMAX)
106# define NSIG (SIGMAX + 1) /* For djgpp */
107# else
108# define NSIG 64 /* Use a reasonable default value */
109# endif
110#endif
111
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200112static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200113#endif /* FAULTHANDLER_USER */
114
115
116static fault_handler_t faulthandler_handlers[] = {
117#ifdef SIGBUS
118 {SIGBUS, 0, "Bus error", },
119#endif
120#ifdef SIGILL
121 {SIGILL, 0, "Illegal instruction", },
122#endif
123 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200124 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200125 /* define SIGSEGV at the end to make it the default choice if searching the
126 handler fails in faulthandler_fatal_error() */
127 {SIGSEGV, 0, "Segmentation fault", }
128};
129static const unsigned char faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200130 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200131
132#ifdef HAVE_SIGALTSTACK
133static stack_t stack;
134#endif
135
136
137/* Get the file descriptor of a file by calling its fileno() method and then
138 call its flush() method.
139
140 If file is NULL or Py_None, use sys.stderr as the new file.
141
142 On success, return the new file and write the file descriptor into *p_fd.
143 On error, return NULL. */
144
145static PyObject*
146faulthandler_get_fileno(PyObject *file, int *p_fd)
147{
148 PyObject *result;
149 long fd_long;
150 int fd;
151
152 if (file == NULL || file == Py_None) {
153 file = PySys_GetObject("stderr");
154 if (file == NULL) {
155 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
156 return NULL;
157 }
158 }
159
160 result = PyObject_CallMethod(file, "fileno", "");
161 if (result == NULL)
162 return NULL;
163
164 fd = -1;
165 if (PyLong_Check(result)) {
166 fd_long = PyLong_AsLong(result);
167 if (0 <= fd_long && fd_long < INT_MAX)
168 fd = (int)fd_long;
169 }
170 Py_DECREF(result);
171
172 if (fd == -1) {
173 PyErr_SetString(PyExc_RuntimeError,
174 "file.fileno() is not a valid file descriptor");
175 return NULL;
176 }
177
178 result = PyObject_CallMethod(file, "flush", "");
179 if (result != NULL)
180 Py_DECREF(result);
181 else {
182 /* ignore flush() error */
183 PyErr_Clear();
184 }
185 *p_fd = fd;
186 return file;
187}
188
Victor Stinnera4de6d82011-04-09 00:47:23 +0200189/* Get the state of the current thread: only call this function if the current
190 thread holds the GIL. Raise an exception on error. */
191static PyThreadState*
192get_thread_state(void)
193{
194 PyThreadState *tstate = PyThreadState_Get();
195 if (tstate == NULL) {
196 PyErr_SetString(PyExc_RuntimeError,
197 "unable to get the current thread state");
198 return NULL;
199 }
200 return tstate;
201}
202
Victor Stinner024e37a2011-03-31 01:31:06 +0200203static PyObject*
204faulthandler_dump_traceback_py(PyObject *self,
205 PyObject *args, PyObject *kwargs)
206{
207 static char *kwlist[] = {"file", "all_threads", NULL};
208 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200209 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200210 PyThreadState *tstate;
211 const char *errmsg;
212 int fd;
213
214 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
215 "|Oi:dump_traceback", kwlist,
216 &file, &all_threads))
217 return NULL;
218
219 file = faulthandler_get_fileno(file, &fd);
220 if (file == NULL)
221 return NULL;
222
Victor Stinnera4de6d82011-04-09 00:47:23 +0200223 tstate = get_thread_state();
224 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200225 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200226
227 if (all_threads) {
228 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
229 if (errmsg != NULL) {
230 PyErr_SetString(PyExc_RuntimeError, errmsg);
231 return NULL;
232 }
233 }
234 else {
235 _Py_DumpTraceback(fd, tstate);
236 }
237 Py_RETURN_NONE;
238}
239
240
Victor Stinner410dd7d2011-05-11 20:56:08 +0200241/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200242
243 Display the current Python traceback, restore the previous handler and call
244 the previous handler.
245
Victor Stinner410dd7d2011-05-11 20:56:08 +0200246 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200247 signal handler would not be called (for an unknown reason). The execution of
248 the program continues at faulthandler_fatal_error() exit, but the same
249 instruction will raise the same fault (signal), and so the previous handler
250 will be called.
251
Victor Stinner410dd7d2011-05-11 20:56:08 +0200252 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200253
254static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200255faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200256{
257 const int fd = fatal_error.fd;
258 unsigned int i;
259 fault_handler_t *handler = NULL;
260 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200261 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200262
263 if (!fatal_error.enabled)
264 return;
265
266 for (i=0; i < faulthandler_nsignals; i++) {
267 handler = &faulthandler_handlers[i];
268 if (handler->signum == signum)
269 break;
270 }
271 if (handler == NULL) {
272 /* faulthandler_nsignals == 0 (unlikely) */
273 return;
274 }
275
276 /* restore the previous handler */
277#ifdef HAVE_SIGACTION
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200278 (void)sigaction(signum, &handler->previous, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200279#else
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200280 (void)signal(signum, handler->previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200281#endif
282 handler->enabled = 0;
283
284 PUTS(fd, "Fatal Python error: ");
285 PUTS(fd, handler->name);
286 PUTS(fd, "\n\n");
287
Victor Stinnerff4cd882011-04-07 11:50:25 +0200288#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200289 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
Victor Stinner410dd7d2011-05-11 20:56:08 +0200290 are thus delivered to the thread that caused the fault. Get the Python
Victor Stinnerd727e232011-04-01 12:13:55 +0200291 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200292
293 PyThreadState_Get() doesn't give the state of the thread that caused the
294 fault if the thread released the GIL, and so this function cannot be
295 used. Read the thread local storage (TLS) instead: call
296 PyGILState_GetThisThreadState(). */
297 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200298#else
299 tstate = PyThreadState_Get();
300#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200301
302 if (fatal_error.all_threads)
Victor Stinnera4de6d82011-04-09 00:47:23 +0200303 _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate);
304 else {
305 if (tstate != NULL)
306 _Py_DumpTraceback(fd, tstate);
307 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200308
Victor Stinnerc9256172011-05-07 12:20:11 +0200309 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200310#ifdef MS_WINDOWS
311 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200312 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200313 handler, because the Windows signal handler would not be called */
314 return;
315 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200316#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200317 /* call the previous signal handler: it is called immediatly if we use
318 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
319 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200320}
321
Victor Stinnerd727e232011-04-01 12:13:55 +0200322/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200323
324static PyObject*
325faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
326{
327 static char *kwlist[] = {"file", "all_threads", NULL};
328 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200329 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200330 unsigned int i;
331 fault_handler_t *handler;
332#ifdef HAVE_SIGACTION
333 struct sigaction action;
334#endif
335 int err;
336 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200337 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200338
339 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
340 "|Oi:enable", kwlist, &file, &all_threads))
341 return NULL;
342
343 file = faulthandler_get_fileno(file, &fd);
344 if (file == NULL)
345 return NULL;
346
Victor Stinnera4de6d82011-04-09 00:47:23 +0200347 tstate = get_thread_state();
348 if (tstate == NULL)
349 return NULL;
350
Victor Stinner024e37a2011-03-31 01:31:06 +0200351 Py_XDECREF(fatal_error.file);
352 Py_INCREF(file);
353 fatal_error.file = file;
354 fatal_error.fd = fd;
355 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200356 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200357
358 if (!fatal_error.enabled) {
359 fatal_error.enabled = 1;
360
361 for (i=0; i < faulthandler_nsignals; i++) {
362 handler = &faulthandler_handlers[i];
363#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200364 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200365 sigemptyset(&action.sa_mask);
366 /* Do not prevent the signal from being received from within
367 its own signal handler */
368 action.sa_flags = SA_NODEFER;
369#ifdef HAVE_SIGALTSTACK
370 if (stack.ss_sp != NULL) {
371 /* Call the signal handler on an alternate signal stack
372 provided by sigaltstack() */
373 action.sa_flags |= SA_ONSTACK;
374 }
375#endif
376 err = sigaction(handler->signum, &action, &handler->previous);
377#else
378 handler->previous = signal(handler->signum,
379 faulthandler_fatal_error);
380 err = (handler->previous == SIG_ERR);
381#endif
382 if (err) {
383 PyErr_SetFromErrno(PyExc_RuntimeError);
384 return NULL;
385 }
386 handler->enabled = 1;
387 }
388 }
389 Py_RETURN_NONE;
390}
391
392static void
393faulthandler_disable(void)
394{
395 unsigned int i;
396 fault_handler_t *handler;
397
398 if (fatal_error.enabled) {
399 fatal_error.enabled = 0;
400 for (i=0; i < faulthandler_nsignals; i++) {
401 handler = &faulthandler_handlers[i];
402 if (!handler->enabled)
403 continue;
404#ifdef HAVE_SIGACTION
405 (void)sigaction(handler->signum, &handler->previous, NULL);
406#else
407 (void)signal(handler->signum, handler->previous);
408#endif
409 handler->enabled = 0;
410 }
411 }
412
413 Py_CLEAR(fatal_error.file);
414}
415
416static PyObject*
417faulthandler_disable_py(PyObject *self)
418{
419 if (!fatal_error.enabled) {
420 Py_INCREF(Py_False);
421 return Py_False;
422 }
423 faulthandler_disable();
424 Py_INCREF(Py_True);
425 return Py_True;
426}
427
428static PyObject*
429faulthandler_is_enabled(PyObject *self)
430{
431 return PyBool_FromLong(fatal_error.enabled);
432}
433
434#ifdef FAULTHANDLER_LATER
435
436static void
437faulthandler_thread(void *unused)
438{
439 PyLockStatus st;
440 const char* errmsg;
441 PyThreadState *current;
442 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200443#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200444 sigset_t set;
445
446 /* we don't want to receive any signal */
447 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200448 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200449#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200450
451 do {
452 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200453 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200454 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200455 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200456 break;
457 }
458 /* Timeout => dump traceback */
459 assert(st == PY_LOCK_FAILURE);
460
461 /* get the thread holding the GIL, NULL if no thread hold the GIL */
462 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
463
Victor Stinnerc790a532011-04-08 13:39:59 +0200464 write(thread.fd, thread.header, thread.header_len);
465
Victor Stinner024e37a2011-03-31 01:31:06 +0200466 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
467 ok = (errmsg == NULL);
468
469 if (thread.exit)
470 _exit(1);
471 } while (ok && thread.repeat);
472
473 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200474 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200475}
476
477static void
Victor Stinnerde10f402011-04-08 12:57:06 +0200478cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200479{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200480 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200481 PyThread_release_lock(thread.cancel_event);
482
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200483 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200484 PyThread_acquire_lock(thread.running, 1);
485 PyThread_release_lock(thread.running);
486
487 /* The main thread should always hold the cancel_event lock */
488 PyThread_acquire_lock(thread.cancel_event, 1);
489
Victor Stinner024e37a2011-03-31 01:31:06 +0200490 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200491 if (thread.header) {
492 free(thread.header);
493 thread.header = NULL;
494 }
495}
496
497static char*
498format_timeout(double timeout)
499{
500 unsigned long us, sec, min, hour;
501 double intpart, fracpart;
502 char buffer[100];
503
504 fracpart = modf(timeout, &intpart);
505 sec = (unsigned long)intpart;
506 us = (unsigned long)(fracpart * 1e6);
507 min = sec / 60;
508 sec %= 60;
509 hour = min / 60;
510 min %= 60;
511
512 if (us != 0)
513 PyOS_snprintf(buffer, sizeof(buffer),
514 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
515 hour, min, sec, us);
516 else
517 PyOS_snprintf(buffer, sizeof(buffer),
518 "Timeout (%lu:%02lu:%02lu)!\n",
519 hour, min, sec);
520
521 return strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200522}
523
524static PyObject*
Victor Stinner96994402011-04-07 11:37:19 +0200525faulthandler_dump_tracebacks_later(PyObject *self,
526 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200527{
528 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
529 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200530 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200531 int repeat = 0;
532 PyObject *file = NULL;
533 int fd;
534 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200535 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200536 char *header;
537 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200538
539 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
540 "d|iOi:dump_tracebacks_later", kwlist,
541 &timeout, &repeat, &file, &exit))
542 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200543 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200544 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
545 return NULL;
546 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200547 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200548 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200549 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
550 return NULL;
551 }
552
Victor Stinnera4de6d82011-04-09 00:47:23 +0200553 tstate = get_thread_state();
554 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200555 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200556
Victor Stinner024e37a2011-03-31 01:31:06 +0200557 file = faulthandler_get_fileno(file, &fd);
558 if (file == NULL)
559 return NULL;
560
Victor Stinnerc790a532011-04-08 13:39:59 +0200561 /* format the timeout */
562 header = format_timeout(timeout);
563 if (header == NULL)
564 return PyErr_NoMemory();
565 header_len = strlen(header);
566
Victor Stinner024e37a2011-03-31 01:31:06 +0200567 /* Cancel previous thread, if running */
Victor Stinnerde10f402011-04-08 12:57:06 +0200568 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200569
570 Py_XDECREF(thread.file);
571 Py_INCREF(file);
572 thread.file = file;
573 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200574 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200575 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200576 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200577 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200578 thread.header = header;
579 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200580
581 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200582 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200583
Victor Stinner024e37a2011-03-31 01:31:06 +0200584 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200585 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200586 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200587 free(header);
588 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200589 PyErr_SetString(PyExc_RuntimeError,
590 "unable to start watchdog thread");
591 return NULL;
592 }
593
594 Py_RETURN_NONE;
595}
596
597static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200598faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200599{
Victor Stinnerde10f402011-04-08 12:57:06 +0200600 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200601 Py_RETURN_NONE;
602}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200603#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200604
Antoine Pitrou75e78b62011-10-04 11:51:23 +0200605#ifdef FAULTHANDLER_WATCHDOG
606
607static void
608file_watchdog(void *unused)
609{
610 PyLockStatus st;
611 PY_TIMEOUT_T timeout;
612
613 const int MAXDATA = 1024;
614 char buf1[MAXDATA], buf2[MAXDATA];
615 char *data = buf1, *old_data = buf2;
616 Py_ssize_t data_len, old_data_len = -1;
617
618#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
619 sigset_t set;
620
621 /* we don't want to receive any signal */
622 sigfillset(&set);
623 pthread_sigmask(SIG_SETMASK, &set, NULL);
624#endif
625
626 /* On first pass, feed file contents immediately */
627 timeout = 0;
628 do {
629 st = PyThread_acquire_lock_timed(watchdog.cancel_event,
630 timeout, 0);
631 timeout = watchdog.period_us;
632 if (st == PY_LOCK_ACQUIRED) {
633 PyThread_release_lock(watchdog.cancel_event);
634 break;
635 }
636 /* Timeout => read and write data */
637 assert(st == PY_LOCK_FAILURE);
638
639 if (lseek(watchdog.rfd, 0, SEEK_SET) < 0) {
640 break;
641 }
642 data_len = read(watchdog.rfd, data, MAXDATA);
643 if (data_len < 0) {
644 break;
645 }
646 if (data_len != old_data_len || memcmp(data, old_data, data_len)) {
647 char *tdata;
648 Py_ssize_t tlen;
649 /* Contents changed, feed them to wfd */
650 long x = (long) data_len;
651 /* We can't do anything if the consumer is too slow, just bail out */
652 if (write(watchdog.wfd, (void *) &x, sizeof(x)) < sizeof(x))
653 break;
654 if (write(watchdog.wfd, data, data_len) < data_len)
655 break;
656 tdata = data;
657 data = old_data;
658 old_data = tdata;
659 tlen = data_len;
660 data_len = old_data_len;
661 old_data_len = tlen;
662 }
663 } while (1);
664
665 close(watchdog.rfd);
666 close(watchdog.wfd);
667
668 /* The only way out */
669 PyThread_release_lock(watchdog.running);
670}
671
672static void
673cancel_file_watchdog(void)
674{
675 /* Notify cancellation */
676 PyThread_release_lock(watchdog.cancel_event);
677
678 /* Wait for thread to join */
679 PyThread_acquire_lock(watchdog.running, 1);
680 PyThread_release_lock(watchdog.running);
681
682 /* The main thread should always hold the cancel_event lock */
683 PyThread_acquire_lock(watchdog.cancel_event, 1);
684}
685
686static PyObject*
687faulthandler_file_watchdog(PyObject *self,
688 PyObject *args, PyObject *kwargs)
689{
690 static char *kwlist[] = {"rfd", "wfd", "period", NULL};
691 double period;
692 PY_TIMEOUT_T period_us;
693 int rfd, wfd;
694
695 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
696 "iid:_file_watchdog", kwlist,
697 &rfd, &wfd, &period))
698 return NULL;
699 if ((period * 1e6) >= (double) PY_TIMEOUT_MAX) {
700 PyErr_SetString(PyExc_OverflowError, "period value is too large");
701 return NULL;
702 }
703 period_us = (PY_TIMEOUT_T)(period * 1e6);
704 if (period_us <= 0) {
705 PyErr_SetString(PyExc_ValueError, "period must be greater than 0");
706 return NULL;
707 }
708
709 /* Cancel previous thread, if running */
710 cancel_file_watchdog();
711
712 watchdog.rfd = rfd;
713 watchdog.wfd = wfd;
714 watchdog.period_us = period_us;
715
716 /* Arm these locks to serve as events when released */
717 PyThread_acquire_lock(watchdog.running, 1);
718
719 if (PyThread_start_new_thread(file_watchdog, NULL) == -1) {
720 PyThread_release_lock(watchdog.running);
721 PyErr_SetString(PyExc_RuntimeError,
722 "unable to start file watchdog thread");
723 return NULL;
724 }
725
726 Py_RETURN_NONE;
727}
728
729static PyObject*
730faulthandler_cancel_file_watchdog(PyObject *self)
731{
732 cancel_file_watchdog();
733 Py_RETURN_NONE;
734}
735#endif /* FAULTHANDLER_WATCHDOG */
736
Victor Stinner024e37a2011-03-31 01:31:06 +0200737#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200738static int
739faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
740{
741#ifdef HAVE_SIGACTION
742 struct sigaction action;
743 action.sa_handler = faulthandler_user;
744 sigemptyset(&action.sa_mask);
745 /* if the signal is received while the kernel is executing a system
746 call, try to restart the system call instead of interrupting it and
747 return EINTR. */
748 action.sa_flags = SA_RESTART;
749 if (chain) {
750 /* do not prevent the signal from being received from within its
751 own signal handler */
752 action.sa_flags = SA_NODEFER;
753 }
754#ifdef HAVE_SIGALTSTACK
755 if (stack.ss_sp != NULL) {
756 /* Call the signal handler on an alternate signal stack
757 provided by sigaltstack() */
758 action.sa_flags |= SA_ONSTACK;
759 }
760#endif
761 return sigaction(signum, &action, p_previous);
762#else
763 _Py_sighandler_t previous;
764 previous = signal(signum, faulthandler_user);
765 if (p_previous != NULL)
766 *p_previous = previous;
767 return (previous == SIG_ERR);
768#endif
769}
770
Victor Stinner024e37a2011-03-31 01:31:06 +0200771/* Handler of user signals (e.g. SIGUSR1).
772
773 Dump the traceback of the current thread, or of all threads if
774 thread.all_threads is true.
775
776 This function is signal safe and should only call signal safe functions. */
777
778static void
779faulthandler_user(int signum)
780{
781 user_signal_t *user;
782 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200783 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200784
785 user = &user_signals[signum];
786 if (!user->enabled)
787 return;
788
Victor Stinnerff4cd882011-04-07 11:50:25 +0200789#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200790 /* PyThreadState_Get() doesn't give the state of the current thread if
791 the thread doesn't hold the GIL. Read the thread local storage (TLS)
792 instead: call PyGILState_GetThisThreadState(). */
793 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200794#else
795 tstate = PyThreadState_Get();
796#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200797
798 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200799 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
800 else {
801 if (tstate == NULL)
802 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200803 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200804 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200805#ifdef HAVE_SIGACTION
806 if (user->chain) {
807 (void)sigaction(signum, &user->previous, NULL);
808 /* call the previous signal handler */
809 raise(signum);
810 (void)faulthandler_register(signum, user->chain, NULL);
811 }
812#else
813 if (user->chain) {
814 /* call the previous signal handler */
815 user->previous(signum);
816 }
817#endif
Victor Stinnerc9256172011-05-07 12:20:11 +0200818 errno = save_errno;
Victor Stinner44378d42011-04-01 15:37:12 +0200819}
820
821static int
822check_signum(int signum)
823{
824 unsigned int i;
825
826 for (i=0; i < faulthandler_nsignals; i++) {
827 if (faulthandler_handlers[i].signum == signum) {
828 PyErr_Format(PyExc_RuntimeError,
829 "signal %i cannot be registered, "
830 "use enable() instead",
831 signum);
832 return 0;
833 }
834 }
835 if (signum < 1 || NSIG <= signum) {
836 PyErr_SetString(PyExc_ValueError, "signal number out of range");
837 return 0;
838 }
839 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200840}
841
842static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200843faulthandler_register_py(PyObject *self,
844 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200845{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200846 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200847 int signum;
848 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200849 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200850 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200851 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200852 user_signal_t *user;
853 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200854 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200855 int err;
856
857 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200858 "i|Oii:register", kwlist,
859 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200860 return NULL;
861
Victor Stinner44378d42011-04-01 15:37:12 +0200862 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200863 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200864
Victor Stinnera4de6d82011-04-09 00:47:23 +0200865 tstate = get_thread_state();
866 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200867 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200868
869 file = faulthandler_get_fileno(file, &fd);
870 if (file == NULL)
871 return NULL;
872
873 if (user_signals == NULL) {
874 user_signals = calloc(NSIG, sizeof(user_signal_t));
875 if (user_signals == NULL)
876 return PyErr_NoMemory();
877 }
878 user = &user_signals[signum];
879
880 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200881 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200882 if (err) {
883 PyErr_SetFromErrno(PyExc_OSError);
884 return NULL;
885 }
886 }
887
888 Py_XDECREF(user->file);
889 Py_INCREF(file);
890 user->file = file;
891 user->fd = fd;
892 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200893 user->chain = chain;
Victor Stinner024e37a2011-03-31 01:31:06 +0200894 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200895 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200896 user->enabled = 1;
897
898 Py_RETURN_NONE;
899}
900
901static int
902faulthandler_unregister(user_signal_t *user, int signum)
903{
Victor Stinnera01ca122011-04-01 12:56:17 +0200904 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200905 return 0;
906 user->enabled = 0;
907#ifdef HAVE_SIGACTION
908 (void)sigaction(signum, &user->previous, NULL);
909#else
910 (void)signal(signum, user->previous);
911#endif
912 Py_CLEAR(user->file);
913 user->fd = -1;
914 return 1;
915}
916
917static PyObject*
918faulthandler_unregister_py(PyObject *self, PyObject *args)
919{
920 int signum;
921 user_signal_t *user;
922 int change;
923
924 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
925 return NULL;
926
Victor Stinner44378d42011-04-01 15:37:12 +0200927 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200928 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200929
Victor Stinnercfa71232011-04-08 12:48:15 +0200930 if (user_signals == NULL)
931 Py_RETURN_FALSE;
932
Victor Stinner024e37a2011-03-31 01:31:06 +0200933 user = &user_signals[signum];
934 change = faulthandler_unregister(user, signum);
935 return PyBool_FromLong(change);
936}
937#endif /* FAULTHANDLER_USER */
938
939
940static PyObject *
941faulthandler_read_null(PyObject *self, PyObject *args)
942{
943 int *x = NULL, y;
944 int release_gil = 0;
945 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
946 return NULL;
947 if (release_gil) {
948 Py_BEGIN_ALLOW_THREADS
949 y = *x;
950 Py_END_ALLOW_THREADS
951 } else
952 y = *x;
953 return PyLong_FromLong(y);
954
955}
956
957static PyObject *
958faulthandler_sigsegv(PyObject *self, PyObject *args)
959{
960#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200961 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
962 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200963 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200964 SIGSEGV was raised by the kernel because of a fault, and so if the
965 program retries to execute the same instruction, the fault will be
966 raised again.
967
968 Here the fault is simulated by a fake SIGSEGV signal raised by the
969 application. We have to raise SIGSEGV at lease twice: once for
970 faulthandler_fatal_error(), and one more time for the previous signal
971 handler. */
972 while(1)
973 raise(SIGSEGV);
974#else
975 raise(SIGSEGV);
976#endif
977 Py_RETURN_NONE;
978}
979
980static PyObject *
981faulthandler_sigfpe(PyObject *self, PyObject *args)
982{
983 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
984 PowerPC. Use volatile to disable compile-time optimizations. */
985 volatile int x = 1, y = 0, z;
986 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +0200987 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
988 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200989 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +0200990 /* This line is never reached, but we pretend to make something with z
991 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +0200992 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +0200993}
994
Victor Stinnerd727e232011-04-01 12:13:55 +0200995static PyObject *
996faulthandler_sigabrt(PyObject *self, PyObject *args)
997{
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200998#ifdef _MSC_VER
999 /* Visual Studio: configure abort() to not display an error message nor
1000 open a popup asking to report the fault. */
1001 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
Victor Stinnerd727e232011-04-01 12:13:55 +02001002#endif
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001003 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001004 Py_RETURN_NONE;
1005}
1006
Victor Stinner024e37a2011-03-31 01:31:06 +02001007#ifdef SIGBUS
1008static PyObject *
1009faulthandler_sigbus(PyObject *self, PyObject *args)
1010{
1011 raise(SIGBUS);
1012 Py_RETURN_NONE;
1013}
1014#endif
1015
1016#ifdef SIGILL
1017static PyObject *
1018faulthandler_sigill(PyObject *self, PyObject *args)
1019{
Victor Stinner024e37a2011-03-31 01:31:06 +02001020 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +02001021 Py_RETURN_NONE;
1022}
1023#endif
1024
1025static PyObject *
1026faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1027{
1028 char *message;
1029 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
1030 return NULL;
1031 Py_FatalError(message);
1032 Py_RETURN_NONE;
1033}
1034
1035#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner9b493042011-05-23 12:29:10 +02001036static void*
Victor Stinnerf0480752011-03-31 11:34:08 +02001037stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001038{
1039 /* allocate 4096 bytes on the stack at each call */
1040 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +02001041 void *sp = &buffer;
1042 *depth += 1;
1043 if (sp < min_sp || max_sp < sp)
1044 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +02001045 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +02001046 buffer[4095] = 0;
1047 return stack_overflow(min_sp, max_sp, depth);
1048}
1049
1050static PyObject *
1051faulthandler_stack_overflow(PyObject *self)
1052{
1053 size_t depth, size;
Victor Stinner425fcd32011-09-07 16:18:56 +02001054 char *sp = (char *)&depth, *stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001055
1056 depth = 0;
1057 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1058 sp + STACK_OVERFLOW_MAX_SIZE,
1059 &depth);
1060 if (sp < stop)
1061 size = stop - sp;
1062 else
1063 size = sp - stop;
1064 PyErr_Format(PyExc_RuntimeError,
1065 "unable to raise a stack overflow (allocated %zu bytes "
1066 "on the stack, %zu recursive calls)",
1067 size, depth);
1068 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001069}
1070#endif
1071
1072
1073static int
1074faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1075{
1076#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +02001077 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001078#endif
1079
1080#ifdef FAULTHANDLER_LATER
1081 Py_VISIT(thread.file);
1082#endif
1083#ifdef FAULTHANDLER_USER
1084 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +02001085 for (signum=0; signum < NSIG; signum++)
1086 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001087 }
1088#endif
1089 Py_VISIT(fatal_error.file);
1090 return 0;
1091}
1092
1093PyDoc_STRVAR(module_doc,
1094"faulthandler module.");
1095
1096static PyMethodDef module_methods[] = {
1097 {"enable",
1098 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001099 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001100 "enable the fault handler")},
1101 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
1102 PyDoc_STR("disable(): disable the fault handler")},
1103 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
1104 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1105 {"dump_traceback",
1106 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001107 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001108 "dump the traceback of the current thread, or of all threads "
1109 "if all_threads is True, into file")},
1110#ifdef FAULTHANDLER_LATER
1111 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +02001112 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
1113 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001114 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001115 "or each timeout seconds if repeat is True. If exit is True, "
1116 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001117 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +02001118 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001119 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
1120 "to dump_tracebacks_later().")},
1121#endif
1122
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001123#ifdef FAULTHANDLER_WATCHDOG
1124 {"_file_watchdog",
1125 (PyCFunction)faulthandler_file_watchdog, METH_VARARGS|METH_KEYWORDS,
1126 PyDoc_STR("_file_watchdog(rfd, wfd, period):\n"
1127 "feed the contents of 'rfd' to 'wfd', if changed,\n"
1128 "every 'period seconds'.")},
1129 {"_cancel_file_watchdog",
1130 (PyCFunction)faulthandler_cancel_file_watchdog, METH_NOARGS,
1131 PyDoc_STR("_cancel_file_watchdog():\ncancel the previous call "
1132 "to _file_watchdog().")},
1133#endif
1134
Victor Stinner024e37a2011-03-31 01:31:06 +02001135#ifdef FAULTHANDLER_USER
1136 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001137 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1138 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001139 "register an handler for the signal 'signum': dump the "
1140 "traceback of the current thread, or of all threads if "
1141 "all_threads is True, into file")},
1142 {"unregister",
1143 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1144 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1145 "'signum' registered by register()")},
1146#endif
1147
1148 {"_read_null", faulthandler_read_null, METH_VARARGS,
1149 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
1150 "a SIGSEGV or SIGBUS signal depending on the platform")},
1151 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
1152 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +02001153 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
1154 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001155 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1156 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
1157#ifdef SIGBUS
1158 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
1159 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
1160#endif
1161#ifdef SIGILL
1162 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
1163 PyDoc_STR("_sigill(): raise a SIGILL signal")},
1164#endif
1165 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1166 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
1167#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1168 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1169 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1170#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001171 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001172};
1173
1174static struct PyModuleDef module_def = {
1175 PyModuleDef_HEAD_INIT,
1176 "faulthandler",
1177 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001178 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001179 module_methods,
1180 NULL,
1181 faulthandler_traverse,
1182 NULL,
1183 NULL
1184};
1185
1186PyMODINIT_FUNC
1187PyInit_faulthandler(void)
1188{
1189 return PyModule_Create(&module_def);
1190}
1191
Victor Stinner410dd7d2011-05-11 20:56:08 +02001192/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1193 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001194
1195static int
1196faulthandler_env_options(void)
1197{
1198 PyObject *xoptions, *key, *module, *res;
Victor Stinner024e37a2011-03-31 01:31:06 +02001199
1200 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
Victor Stinner25095b22011-05-26 13:47:08 +02001201 int has_key;
1202
Victor Stinner024e37a2011-03-31 01:31:06 +02001203 xoptions = PySys_GetXOptions();
1204 if (xoptions == NULL)
1205 return -1;
1206
1207 key = PyUnicode_FromString("faulthandler");
1208 if (key == NULL)
1209 return -1;
1210
Victor Stinner25095b22011-05-26 13:47:08 +02001211 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001212 Py_DECREF(key);
Victor Stinner25095b22011-05-26 13:47:08 +02001213 if (!has_key)
Victor Stinner024e37a2011-03-31 01:31:06 +02001214 return 0;
1215 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001216
1217 module = PyImport_ImportModule("faulthandler");
1218 if (module == NULL) {
1219 return -1;
1220 }
1221 res = PyObject_CallMethod(module, "enable", "");
1222 Py_DECREF(module);
1223 if (res == NULL)
1224 return -1;
1225 Py_DECREF(res);
1226 return 0;
1227}
1228
1229int _PyFaulthandler_Init(void)
1230{
1231#ifdef HAVE_SIGALTSTACK
1232 int err;
1233
1234 /* Try to allocate an alternate stack for faulthandler() signal handler to
1235 * be able to allocate memory on the stack, even on a stack overflow. If it
1236 * fails, ignore the error. */
1237 stack.ss_flags = 0;
1238 stack.ss_size = SIGSTKSZ;
1239 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1240 if (stack.ss_sp != NULL) {
1241 err = sigaltstack(&stack, NULL);
1242 if (err) {
1243 PyMem_Free(stack.ss_sp);
1244 stack.ss_sp = NULL;
1245 }
1246 }
1247#endif
1248#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001249 thread.file = NULL;
1250 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001251 thread.running = PyThread_allocate_lock();
1252 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001253 PyErr_SetString(PyExc_RuntimeError,
1254 "could not allocate locks for faulthandler");
1255 return -1;
1256 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001257 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001258#endif
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001259#ifdef FAULTHANDLER_WATCHDOG
1260 watchdog.cancel_event = PyThread_allocate_lock();
1261 watchdog.running = PyThread_allocate_lock();
1262 if (!watchdog.cancel_event || !watchdog.running) {
1263 PyErr_SetString(PyExc_RuntimeError,
1264 "could not allocate locks for faulthandler");
1265 return -1;
1266 }
1267 PyThread_acquire_lock(watchdog.cancel_event, 1);
1268#endif
Victor Stinner024e37a2011-03-31 01:31:06 +02001269
1270 return faulthandler_env_options();
1271}
1272
1273void _PyFaulthandler_Fini(void)
1274{
1275#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001276 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001277#endif
1278
1279#ifdef FAULTHANDLER_LATER
1280 /* later */
Victor Stinnerde10f402011-04-08 12:57:06 +02001281 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001282 if (thread.cancel_event) {
Victor Stinnerde10f402011-04-08 12:57:06 +02001283 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001284 PyThread_free_lock(thread.cancel_event);
1285 thread.cancel_event = NULL;
1286 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001287 if (thread.running) {
1288 PyThread_free_lock(thread.running);
1289 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001290 }
1291#endif
1292
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001293#ifdef FAULTHANDLER_WATCHDOG
1294 /* file watchdog */
1295 cancel_file_watchdog();
1296 if (watchdog.cancel_event) {
1297 PyThread_release_lock(watchdog.cancel_event);
1298 PyThread_free_lock(watchdog.cancel_event);
1299 watchdog.cancel_event = NULL;
1300 }
1301 if (watchdog.running) {
1302 PyThread_free_lock(watchdog.running);
1303 watchdog.running = NULL;
1304 }
1305#endif
1306
Victor Stinner024e37a2011-03-31 01:31:06 +02001307#ifdef FAULTHANDLER_USER
1308 /* user */
1309 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001310 for (signum=0; signum < NSIG; signum++)
1311 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001312 free(user_signals);
1313 user_signals = NULL;
1314 }
1315#endif
1316
1317 /* fatal */
1318 faulthandler_disable();
1319#ifdef HAVE_SIGALTSTACK
1320 if (stack.ss_sp != NULL) {
1321 PyMem_Free(stack.ss_sp);
1322 stack.ss_sp = NULL;
1323 }
1324#endif
1325}