blob: 06f7f2e8c3a3815087fded0adedd45ab85190199 [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
Antoine Pitroub244d072011-10-04 13:00:02 +0200613#define MAXDATA 1024
Antoine Pitrou75e78b62011-10-04 11:51:23 +0200614 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);
Antoine Pitroub244d072011-10-04 13:00:02 +0200670#undef MAXDATA
Antoine Pitrou75e78b62011-10-04 11:51:23 +0200671}
672
673static void
674cancel_file_watchdog(void)
675{
676 /* Notify cancellation */
677 PyThread_release_lock(watchdog.cancel_event);
678
679 /* Wait for thread to join */
680 PyThread_acquire_lock(watchdog.running, 1);
681 PyThread_release_lock(watchdog.running);
682
683 /* The main thread should always hold the cancel_event lock */
684 PyThread_acquire_lock(watchdog.cancel_event, 1);
685}
686
687static PyObject*
688faulthandler_file_watchdog(PyObject *self,
689 PyObject *args, PyObject *kwargs)
690{
691 static char *kwlist[] = {"rfd", "wfd", "period", NULL};
692 double period;
693 PY_TIMEOUT_T period_us;
694 int rfd, wfd;
695
696 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
697 "iid:_file_watchdog", kwlist,
698 &rfd, &wfd, &period))
699 return NULL;
700 if ((period * 1e6) >= (double) PY_TIMEOUT_MAX) {
701 PyErr_SetString(PyExc_OverflowError, "period value is too large");
702 return NULL;
703 }
704 period_us = (PY_TIMEOUT_T)(period * 1e6);
705 if (period_us <= 0) {
706 PyErr_SetString(PyExc_ValueError, "period must be greater than 0");
707 return NULL;
708 }
709
710 /* Cancel previous thread, if running */
711 cancel_file_watchdog();
712
713 watchdog.rfd = rfd;
714 watchdog.wfd = wfd;
715 watchdog.period_us = period_us;
716
717 /* Arm these locks to serve as events when released */
718 PyThread_acquire_lock(watchdog.running, 1);
719
720 if (PyThread_start_new_thread(file_watchdog, NULL) == -1) {
721 PyThread_release_lock(watchdog.running);
722 PyErr_SetString(PyExc_RuntimeError,
723 "unable to start file watchdog thread");
724 return NULL;
725 }
726
727 Py_RETURN_NONE;
728}
729
730static PyObject*
731faulthandler_cancel_file_watchdog(PyObject *self)
732{
733 cancel_file_watchdog();
734 Py_RETURN_NONE;
735}
736#endif /* FAULTHANDLER_WATCHDOG */
737
Victor Stinner024e37a2011-03-31 01:31:06 +0200738#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200739static int
740faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
741{
742#ifdef HAVE_SIGACTION
743 struct sigaction action;
744 action.sa_handler = faulthandler_user;
745 sigemptyset(&action.sa_mask);
746 /* if the signal is received while the kernel is executing a system
747 call, try to restart the system call instead of interrupting it and
748 return EINTR. */
749 action.sa_flags = SA_RESTART;
750 if (chain) {
751 /* do not prevent the signal from being received from within its
752 own signal handler */
753 action.sa_flags = SA_NODEFER;
754 }
755#ifdef HAVE_SIGALTSTACK
756 if (stack.ss_sp != NULL) {
757 /* Call the signal handler on an alternate signal stack
758 provided by sigaltstack() */
759 action.sa_flags |= SA_ONSTACK;
760 }
761#endif
762 return sigaction(signum, &action, p_previous);
763#else
764 _Py_sighandler_t previous;
765 previous = signal(signum, faulthandler_user);
766 if (p_previous != NULL)
767 *p_previous = previous;
768 return (previous == SIG_ERR);
769#endif
770}
771
Victor Stinner024e37a2011-03-31 01:31:06 +0200772/* Handler of user signals (e.g. SIGUSR1).
773
774 Dump the traceback of the current thread, or of all threads if
775 thread.all_threads is true.
776
777 This function is signal safe and should only call signal safe functions. */
778
779static void
780faulthandler_user(int signum)
781{
782 user_signal_t *user;
783 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200784 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200785
786 user = &user_signals[signum];
787 if (!user->enabled)
788 return;
789
Victor Stinnerff4cd882011-04-07 11:50:25 +0200790#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200791 /* PyThreadState_Get() doesn't give the state of the current thread if
792 the thread doesn't hold the GIL. Read the thread local storage (TLS)
793 instead: call PyGILState_GetThisThreadState(). */
794 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200795#else
796 tstate = PyThreadState_Get();
797#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200798
799 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200800 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
801 else {
802 if (tstate == NULL)
803 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200804 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200805 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200806#ifdef HAVE_SIGACTION
807 if (user->chain) {
808 (void)sigaction(signum, &user->previous, NULL);
809 /* call the previous signal handler */
810 raise(signum);
811 (void)faulthandler_register(signum, user->chain, NULL);
812 }
813#else
814 if (user->chain) {
815 /* call the previous signal handler */
816 user->previous(signum);
817 }
818#endif
Victor Stinnerc9256172011-05-07 12:20:11 +0200819 errno = save_errno;
Victor Stinner44378d42011-04-01 15:37:12 +0200820}
821
822static int
823check_signum(int signum)
824{
825 unsigned int i;
826
827 for (i=0; i < faulthandler_nsignals; i++) {
828 if (faulthandler_handlers[i].signum == signum) {
829 PyErr_Format(PyExc_RuntimeError,
830 "signal %i cannot be registered, "
831 "use enable() instead",
832 signum);
833 return 0;
834 }
835 }
836 if (signum < 1 || NSIG <= signum) {
837 PyErr_SetString(PyExc_ValueError, "signal number out of range");
838 return 0;
839 }
840 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200841}
842
843static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200844faulthandler_register_py(PyObject *self,
845 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200846{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200847 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200848 int signum;
849 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200850 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200851 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200852 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200853 user_signal_t *user;
854 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200855 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200856 int err;
857
858 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200859 "i|Oii:register", kwlist,
860 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200861 return NULL;
862
Victor Stinner44378d42011-04-01 15:37:12 +0200863 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200864 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200865
Victor Stinnera4de6d82011-04-09 00:47:23 +0200866 tstate = get_thread_state();
867 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200868 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200869
870 file = faulthandler_get_fileno(file, &fd);
871 if (file == NULL)
872 return NULL;
873
874 if (user_signals == NULL) {
875 user_signals = calloc(NSIG, sizeof(user_signal_t));
876 if (user_signals == NULL)
877 return PyErr_NoMemory();
878 }
879 user = &user_signals[signum];
880
881 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200882 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200883 if (err) {
884 PyErr_SetFromErrno(PyExc_OSError);
885 return NULL;
886 }
887 }
888
889 Py_XDECREF(user->file);
890 Py_INCREF(file);
891 user->file = file;
892 user->fd = fd;
893 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200894 user->chain = chain;
Victor Stinner024e37a2011-03-31 01:31:06 +0200895 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200896 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200897 user->enabled = 1;
898
899 Py_RETURN_NONE;
900}
901
902static int
903faulthandler_unregister(user_signal_t *user, int signum)
904{
Victor Stinnera01ca122011-04-01 12:56:17 +0200905 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200906 return 0;
907 user->enabled = 0;
908#ifdef HAVE_SIGACTION
909 (void)sigaction(signum, &user->previous, NULL);
910#else
911 (void)signal(signum, user->previous);
912#endif
913 Py_CLEAR(user->file);
914 user->fd = -1;
915 return 1;
916}
917
918static PyObject*
919faulthandler_unregister_py(PyObject *self, PyObject *args)
920{
921 int signum;
922 user_signal_t *user;
923 int change;
924
925 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
926 return NULL;
927
Victor Stinner44378d42011-04-01 15:37:12 +0200928 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200929 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200930
Victor Stinnercfa71232011-04-08 12:48:15 +0200931 if (user_signals == NULL)
932 Py_RETURN_FALSE;
933
Victor Stinner024e37a2011-03-31 01:31:06 +0200934 user = &user_signals[signum];
935 change = faulthandler_unregister(user, signum);
936 return PyBool_FromLong(change);
937}
938#endif /* FAULTHANDLER_USER */
939
940
941static PyObject *
942faulthandler_read_null(PyObject *self, PyObject *args)
943{
944 int *x = NULL, y;
945 int release_gil = 0;
946 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
947 return NULL;
948 if (release_gil) {
949 Py_BEGIN_ALLOW_THREADS
950 y = *x;
951 Py_END_ALLOW_THREADS
952 } else
953 y = *x;
954 return PyLong_FromLong(y);
955
956}
957
958static PyObject *
959faulthandler_sigsegv(PyObject *self, PyObject *args)
960{
961#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200962 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
963 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200964 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200965 SIGSEGV was raised by the kernel because of a fault, and so if the
966 program retries to execute the same instruction, the fault will be
967 raised again.
968
969 Here the fault is simulated by a fake SIGSEGV signal raised by the
970 application. We have to raise SIGSEGV at lease twice: once for
971 faulthandler_fatal_error(), and one more time for the previous signal
972 handler. */
973 while(1)
974 raise(SIGSEGV);
975#else
976 raise(SIGSEGV);
977#endif
978 Py_RETURN_NONE;
979}
980
981static PyObject *
982faulthandler_sigfpe(PyObject *self, PyObject *args)
983{
984 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
985 PowerPC. Use volatile to disable compile-time optimizations. */
986 volatile int x = 1, y = 0, z;
987 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +0200988 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
989 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200990 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +0200991 /* This line is never reached, but we pretend to make something with z
992 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +0200993 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +0200994}
995
Victor Stinnerd727e232011-04-01 12:13:55 +0200996static PyObject *
997faulthandler_sigabrt(PyObject *self, PyObject *args)
998{
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200999#ifdef _MSC_VER
1000 /* Visual Studio: configure abort() to not display an error message nor
1001 open a popup asking to report the fault. */
1002 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
Victor Stinnerd727e232011-04-01 12:13:55 +02001003#endif
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001004 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001005 Py_RETURN_NONE;
1006}
1007
Victor Stinner024e37a2011-03-31 01:31:06 +02001008#ifdef SIGBUS
1009static PyObject *
1010faulthandler_sigbus(PyObject *self, PyObject *args)
1011{
1012 raise(SIGBUS);
1013 Py_RETURN_NONE;
1014}
1015#endif
1016
1017#ifdef SIGILL
1018static PyObject *
1019faulthandler_sigill(PyObject *self, PyObject *args)
1020{
Victor Stinner024e37a2011-03-31 01:31:06 +02001021 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +02001022 Py_RETURN_NONE;
1023}
1024#endif
1025
1026static PyObject *
1027faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1028{
1029 char *message;
1030 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
1031 return NULL;
1032 Py_FatalError(message);
1033 Py_RETURN_NONE;
1034}
1035
1036#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner9b493042011-05-23 12:29:10 +02001037static void*
Victor Stinnerf0480752011-03-31 11:34:08 +02001038stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001039{
1040 /* allocate 4096 bytes on the stack at each call */
1041 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +02001042 void *sp = &buffer;
1043 *depth += 1;
1044 if (sp < min_sp || max_sp < sp)
1045 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +02001046 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +02001047 buffer[4095] = 0;
1048 return stack_overflow(min_sp, max_sp, depth);
1049}
1050
1051static PyObject *
1052faulthandler_stack_overflow(PyObject *self)
1053{
1054 size_t depth, size;
Victor Stinner425fcd32011-09-07 16:18:56 +02001055 char *sp = (char *)&depth, *stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001056
1057 depth = 0;
1058 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1059 sp + STACK_OVERFLOW_MAX_SIZE,
1060 &depth);
1061 if (sp < stop)
1062 size = stop - sp;
1063 else
1064 size = sp - stop;
1065 PyErr_Format(PyExc_RuntimeError,
1066 "unable to raise a stack overflow (allocated %zu bytes "
1067 "on the stack, %zu recursive calls)",
1068 size, depth);
1069 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001070}
1071#endif
1072
1073
1074static int
1075faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1076{
1077#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +02001078 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001079#endif
1080
1081#ifdef FAULTHANDLER_LATER
1082 Py_VISIT(thread.file);
1083#endif
1084#ifdef FAULTHANDLER_USER
1085 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +02001086 for (signum=0; signum < NSIG; signum++)
1087 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001088 }
1089#endif
1090 Py_VISIT(fatal_error.file);
1091 return 0;
1092}
1093
1094PyDoc_STRVAR(module_doc,
1095"faulthandler module.");
1096
1097static PyMethodDef module_methods[] = {
1098 {"enable",
1099 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001100 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001101 "enable the fault handler")},
1102 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
1103 PyDoc_STR("disable(): disable the fault handler")},
1104 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
1105 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1106 {"dump_traceback",
1107 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001108 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001109 "dump the traceback of the current thread, or of all threads "
1110 "if all_threads is True, into file")},
1111#ifdef FAULTHANDLER_LATER
1112 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +02001113 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
1114 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001115 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001116 "or each timeout seconds if repeat is True. If exit is True, "
1117 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001118 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +02001119 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001120 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
1121 "to dump_tracebacks_later().")},
1122#endif
1123
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001124#ifdef FAULTHANDLER_WATCHDOG
1125 {"_file_watchdog",
1126 (PyCFunction)faulthandler_file_watchdog, METH_VARARGS|METH_KEYWORDS,
1127 PyDoc_STR("_file_watchdog(rfd, wfd, period):\n"
1128 "feed the contents of 'rfd' to 'wfd', if changed,\n"
1129 "every 'period seconds'.")},
1130 {"_cancel_file_watchdog",
1131 (PyCFunction)faulthandler_cancel_file_watchdog, METH_NOARGS,
1132 PyDoc_STR("_cancel_file_watchdog():\ncancel the previous call "
1133 "to _file_watchdog().")},
1134#endif
1135
Victor Stinner024e37a2011-03-31 01:31:06 +02001136#ifdef FAULTHANDLER_USER
1137 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001138 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1139 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001140 "register an handler for the signal 'signum': dump the "
1141 "traceback of the current thread, or of all threads if "
1142 "all_threads is True, into file")},
1143 {"unregister",
1144 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1145 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1146 "'signum' registered by register()")},
1147#endif
1148
1149 {"_read_null", faulthandler_read_null, METH_VARARGS,
1150 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
1151 "a SIGSEGV or SIGBUS signal depending on the platform")},
1152 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
1153 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +02001154 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
1155 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001156 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1157 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
1158#ifdef SIGBUS
1159 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
1160 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
1161#endif
1162#ifdef SIGILL
1163 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
1164 PyDoc_STR("_sigill(): raise a SIGILL signal")},
1165#endif
1166 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1167 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
1168#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1169 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1170 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1171#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001172 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001173};
1174
1175static struct PyModuleDef module_def = {
1176 PyModuleDef_HEAD_INIT,
1177 "faulthandler",
1178 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001179 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001180 module_methods,
1181 NULL,
1182 faulthandler_traverse,
1183 NULL,
1184 NULL
1185};
1186
1187PyMODINIT_FUNC
1188PyInit_faulthandler(void)
1189{
1190 return PyModule_Create(&module_def);
1191}
1192
Victor Stinner410dd7d2011-05-11 20:56:08 +02001193/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1194 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001195
1196static int
1197faulthandler_env_options(void)
1198{
1199 PyObject *xoptions, *key, *module, *res;
Victor Stinner024e37a2011-03-31 01:31:06 +02001200
1201 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
Victor Stinner25095b22011-05-26 13:47:08 +02001202 int has_key;
1203
Victor Stinner024e37a2011-03-31 01:31:06 +02001204 xoptions = PySys_GetXOptions();
1205 if (xoptions == NULL)
1206 return -1;
1207
1208 key = PyUnicode_FromString("faulthandler");
1209 if (key == NULL)
1210 return -1;
1211
Victor Stinner25095b22011-05-26 13:47:08 +02001212 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001213 Py_DECREF(key);
Victor Stinner25095b22011-05-26 13:47:08 +02001214 if (!has_key)
Victor Stinner024e37a2011-03-31 01:31:06 +02001215 return 0;
1216 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001217
1218 module = PyImport_ImportModule("faulthandler");
1219 if (module == NULL) {
1220 return -1;
1221 }
1222 res = PyObject_CallMethod(module, "enable", "");
1223 Py_DECREF(module);
1224 if (res == NULL)
1225 return -1;
1226 Py_DECREF(res);
1227 return 0;
1228}
1229
1230int _PyFaulthandler_Init(void)
1231{
1232#ifdef HAVE_SIGALTSTACK
1233 int err;
1234
1235 /* Try to allocate an alternate stack for faulthandler() signal handler to
1236 * be able to allocate memory on the stack, even on a stack overflow. If it
1237 * fails, ignore the error. */
1238 stack.ss_flags = 0;
1239 stack.ss_size = SIGSTKSZ;
1240 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1241 if (stack.ss_sp != NULL) {
1242 err = sigaltstack(&stack, NULL);
1243 if (err) {
1244 PyMem_Free(stack.ss_sp);
1245 stack.ss_sp = NULL;
1246 }
1247 }
1248#endif
1249#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001250 thread.file = NULL;
1251 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001252 thread.running = PyThread_allocate_lock();
1253 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001254 PyErr_SetString(PyExc_RuntimeError,
1255 "could not allocate locks for faulthandler");
1256 return -1;
1257 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001258 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001259#endif
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001260#ifdef FAULTHANDLER_WATCHDOG
1261 watchdog.cancel_event = PyThread_allocate_lock();
1262 watchdog.running = PyThread_allocate_lock();
1263 if (!watchdog.cancel_event || !watchdog.running) {
1264 PyErr_SetString(PyExc_RuntimeError,
1265 "could not allocate locks for faulthandler");
1266 return -1;
1267 }
1268 PyThread_acquire_lock(watchdog.cancel_event, 1);
1269#endif
Victor Stinner024e37a2011-03-31 01:31:06 +02001270
1271 return faulthandler_env_options();
1272}
1273
1274void _PyFaulthandler_Fini(void)
1275{
1276#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001277 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001278#endif
1279
1280#ifdef FAULTHANDLER_LATER
1281 /* later */
Victor Stinnerde10f402011-04-08 12:57:06 +02001282 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001283 if (thread.cancel_event) {
Victor Stinnerde10f402011-04-08 12:57:06 +02001284 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001285 PyThread_free_lock(thread.cancel_event);
1286 thread.cancel_event = NULL;
1287 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001288 if (thread.running) {
1289 PyThread_free_lock(thread.running);
1290 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001291 }
1292#endif
1293
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001294#ifdef FAULTHANDLER_WATCHDOG
1295 /* file watchdog */
1296 cancel_file_watchdog();
1297 if (watchdog.cancel_event) {
1298 PyThread_release_lock(watchdog.cancel_event);
1299 PyThread_free_lock(watchdog.cancel_event);
1300 watchdog.cancel_event = NULL;
1301 }
1302 if (watchdog.running) {
1303 PyThread_free_lock(watchdog.running);
1304 watchdog.running = NULL;
1305 }
1306#endif
1307
Victor Stinner024e37a2011-03-31 01:31:06 +02001308#ifdef FAULTHANDLER_USER
1309 /* user */
1310 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001311 for (signum=0; signum < NSIG; signum++)
1312 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001313 free(user_signals);
1314 user_signals = NULL;
1315 }
1316#endif
1317
1318 /* fatal */
1319 faulthandler_disable();
1320#ifdef HAVE_SIGALTSTACK
1321 if (stack.ss_sp != NULL) {
1322 PyMem_Free(stack.ss_sp);
1323 stack.ss_sp = NULL;
1324 }
1325#endif
1326}