blob: 51c66bdd659ffd88c3a621eba5e21b5ad9b8aed1 [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;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200149 _Py_IDENTIFIER(fileno);
150 _Py_IDENTIFIER(flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200151 long fd_long;
152 int fd;
153
154 if (file == NULL || file == Py_None) {
155 file = PySys_GetObject("stderr");
156 if (file == NULL) {
157 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
158 return NULL;
159 }
160 }
161
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200162 result = _PyObject_CallMethodId(file, &PyId_fileno, "");
Victor Stinner024e37a2011-03-31 01:31:06 +0200163 if (result == NULL)
164 return NULL;
165
166 fd = -1;
167 if (PyLong_Check(result)) {
168 fd_long = PyLong_AsLong(result);
169 if (0 <= fd_long && fd_long < INT_MAX)
170 fd = (int)fd_long;
171 }
172 Py_DECREF(result);
173
174 if (fd == -1) {
175 PyErr_SetString(PyExc_RuntimeError,
176 "file.fileno() is not a valid file descriptor");
177 return NULL;
178 }
179
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200180 result = _PyObject_CallMethodId(file, &PyId_flush, "");
Victor Stinner024e37a2011-03-31 01:31:06 +0200181 if (result != NULL)
182 Py_DECREF(result);
183 else {
184 /* ignore flush() error */
185 PyErr_Clear();
186 }
187 *p_fd = fd;
188 return file;
189}
190
Victor Stinnera4de6d82011-04-09 00:47:23 +0200191/* Get the state of the current thread: only call this function if the current
192 thread holds the GIL. Raise an exception on error. */
193static PyThreadState*
194get_thread_state(void)
195{
196 PyThreadState *tstate = PyThreadState_Get();
197 if (tstate == NULL) {
198 PyErr_SetString(PyExc_RuntimeError,
199 "unable to get the current thread state");
200 return NULL;
201 }
202 return tstate;
203}
204
Victor Stinner024e37a2011-03-31 01:31:06 +0200205static PyObject*
206faulthandler_dump_traceback_py(PyObject *self,
207 PyObject *args, PyObject *kwargs)
208{
209 static char *kwlist[] = {"file", "all_threads", NULL};
210 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200211 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200212 PyThreadState *tstate;
213 const char *errmsg;
214 int fd;
215
216 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
217 "|Oi:dump_traceback", kwlist,
218 &file, &all_threads))
219 return NULL;
220
221 file = faulthandler_get_fileno(file, &fd);
222 if (file == NULL)
223 return NULL;
224
Victor Stinnera4de6d82011-04-09 00:47:23 +0200225 tstate = get_thread_state();
226 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200227 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200228
229 if (all_threads) {
230 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
231 if (errmsg != NULL) {
232 PyErr_SetString(PyExc_RuntimeError, errmsg);
233 return NULL;
234 }
235 }
236 else {
237 _Py_DumpTraceback(fd, tstate);
238 }
239 Py_RETURN_NONE;
240}
241
242
Victor Stinner410dd7d2011-05-11 20:56:08 +0200243/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200244
245 Display the current Python traceback, restore the previous handler and call
246 the previous handler.
247
Victor Stinner410dd7d2011-05-11 20:56:08 +0200248 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200249 signal handler would not be called (for an unknown reason). The execution of
250 the program continues at faulthandler_fatal_error() exit, but the same
251 instruction will raise the same fault (signal), and so the previous handler
252 will be called.
253
Victor Stinner410dd7d2011-05-11 20:56:08 +0200254 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200255
256static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200257faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200258{
259 const int fd = fatal_error.fd;
260 unsigned int i;
261 fault_handler_t *handler = NULL;
262 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200263 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200264
265 if (!fatal_error.enabled)
266 return;
267
268 for (i=0; i < faulthandler_nsignals; i++) {
269 handler = &faulthandler_handlers[i];
270 if (handler->signum == signum)
271 break;
272 }
273 if (handler == NULL) {
274 /* faulthandler_nsignals == 0 (unlikely) */
275 return;
276 }
277
278 /* restore the previous handler */
279#ifdef HAVE_SIGACTION
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200280 (void)sigaction(signum, &handler->previous, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200281#else
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200282 (void)signal(signum, handler->previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200283#endif
284 handler->enabled = 0;
285
286 PUTS(fd, "Fatal Python error: ");
287 PUTS(fd, handler->name);
288 PUTS(fd, "\n\n");
289
Victor Stinnerff4cd882011-04-07 11:50:25 +0200290#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200291 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
Victor Stinner410dd7d2011-05-11 20:56:08 +0200292 are thus delivered to the thread that caused the fault. Get the Python
Victor Stinnerd727e232011-04-01 12:13:55 +0200293 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200294
295 PyThreadState_Get() doesn't give the state of the thread that caused the
296 fault if the thread released the GIL, and so this function cannot be
297 used. Read the thread local storage (TLS) instead: call
298 PyGILState_GetThisThreadState(). */
299 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200300#else
301 tstate = PyThreadState_Get();
302#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200303
304 if (fatal_error.all_threads)
Victor Stinnera4de6d82011-04-09 00:47:23 +0200305 _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate);
306 else {
307 if (tstate != NULL)
308 _Py_DumpTraceback(fd, tstate);
309 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200310
Victor Stinnerc9256172011-05-07 12:20:11 +0200311 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200312#ifdef MS_WINDOWS
313 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200314 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200315 handler, because the Windows signal handler would not be called */
316 return;
317 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200318#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200319 /* call the previous signal handler: it is called immediatly if we use
320 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
321 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200322}
323
Victor Stinnerd727e232011-04-01 12:13:55 +0200324/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200325
326static PyObject*
327faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
328{
329 static char *kwlist[] = {"file", "all_threads", NULL};
330 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200331 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200332 unsigned int i;
333 fault_handler_t *handler;
334#ifdef HAVE_SIGACTION
335 struct sigaction action;
336#endif
337 int err;
338 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200339 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200340
341 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
342 "|Oi:enable", kwlist, &file, &all_threads))
343 return NULL;
344
345 file = faulthandler_get_fileno(file, &fd);
346 if (file == NULL)
347 return NULL;
348
Victor Stinnera4de6d82011-04-09 00:47:23 +0200349 tstate = get_thread_state();
350 if (tstate == NULL)
351 return NULL;
352
Victor Stinner024e37a2011-03-31 01:31:06 +0200353 Py_XDECREF(fatal_error.file);
354 Py_INCREF(file);
355 fatal_error.file = file;
356 fatal_error.fd = fd;
357 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200358 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200359
360 if (!fatal_error.enabled) {
361 fatal_error.enabled = 1;
362
363 for (i=0; i < faulthandler_nsignals; i++) {
364 handler = &faulthandler_handlers[i];
365#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200366 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200367 sigemptyset(&action.sa_mask);
368 /* Do not prevent the signal from being received from within
369 its own signal handler */
370 action.sa_flags = SA_NODEFER;
371#ifdef HAVE_SIGALTSTACK
372 if (stack.ss_sp != NULL) {
373 /* Call the signal handler on an alternate signal stack
374 provided by sigaltstack() */
375 action.sa_flags |= SA_ONSTACK;
376 }
377#endif
378 err = sigaction(handler->signum, &action, &handler->previous);
379#else
380 handler->previous = signal(handler->signum,
381 faulthandler_fatal_error);
382 err = (handler->previous == SIG_ERR);
383#endif
384 if (err) {
385 PyErr_SetFromErrno(PyExc_RuntimeError);
386 return NULL;
387 }
388 handler->enabled = 1;
389 }
390 }
391 Py_RETURN_NONE;
392}
393
394static void
395faulthandler_disable(void)
396{
397 unsigned int i;
398 fault_handler_t *handler;
399
400 if (fatal_error.enabled) {
401 fatal_error.enabled = 0;
402 for (i=0; i < faulthandler_nsignals; i++) {
403 handler = &faulthandler_handlers[i];
404 if (!handler->enabled)
405 continue;
406#ifdef HAVE_SIGACTION
407 (void)sigaction(handler->signum, &handler->previous, NULL);
408#else
409 (void)signal(handler->signum, handler->previous);
410#endif
411 handler->enabled = 0;
412 }
413 }
414
415 Py_CLEAR(fatal_error.file);
416}
417
418static PyObject*
419faulthandler_disable_py(PyObject *self)
420{
421 if (!fatal_error.enabled) {
422 Py_INCREF(Py_False);
423 return Py_False;
424 }
425 faulthandler_disable();
426 Py_INCREF(Py_True);
427 return Py_True;
428}
429
430static PyObject*
431faulthandler_is_enabled(PyObject *self)
432{
433 return PyBool_FromLong(fatal_error.enabled);
434}
435
436#ifdef FAULTHANDLER_LATER
437
438static void
439faulthandler_thread(void *unused)
440{
441 PyLockStatus st;
442 const char* errmsg;
443 PyThreadState *current;
444 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200445#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200446 sigset_t set;
447
448 /* we don't want to receive any signal */
449 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200450 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200451#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200452
453 do {
454 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200455 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200456 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200457 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200458 break;
459 }
460 /* Timeout => dump traceback */
461 assert(st == PY_LOCK_FAILURE);
462
463 /* get the thread holding the GIL, NULL if no thread hold the GIL */
464 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
465
Victor Stinnerc790a532011-04-08 13:39:59 +0200466 write(thread.fd, thread.header, thread.header_len);
467
Victor Stinner024e37a2011-03-31 01:31:06 +0200468 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
469 ok = (errmsg == NULL);
470
471 if (thread.exit)
472 _exit(1);
473 } while (ok && thread.repeat);
474
475 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200476 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200477}
478
479static void
Victor Stinnerde10f402011-04-08 12:57:06 +0200480cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200481{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200482 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200483 PyThread_release_lock(thread.cancel_event);
484
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200485 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200486 PyThread_acquire_lock(thread.running, 1);
487 PyThread_release_lock(thread.running);
488
489 /* The main thread should always hold the cancel_event lock */
490 PyThread_acquire_lock(thread.cancel_event, 1);
491
Victor Stinner024e37a2011-03-31 01:31:06 +0200492 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200493 if (thread.header) {
494 free(thread.header);
495 thread.header = NULL;
496 }
497}
498
499static char*
500format_timeout(double timeout)
501{
502 unsigned long us, sec, min, hour;
503 double intpart, fracpart;
504 char buffer[100];
505
506 fracpart = modf(timeout, &intpart);
507 sec = (unsigned long)intpart;
508 us = (unsigned long)(fracpart * 1e6);
509 min = sec / 60;
510 sec %= 60;
511 hour = min / 60;
512 min %= 60;
513
514 if (us != 0)
515 PyOS_snprintf(buffer, sizeof(buffer),
516 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
517 hour, min, sec, us);
518 else
519 PyOS_snprintf(buffer, sizeof(buffer),
520 "Timeout (%lu:%02lu:%02lu)!\n",
521 hour, min, sec);
522
523 return strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200524}
525
526static PyObject*
Victor Stinner96994402011-04-07 11:37:19 +0200527faulthandler_dump_tracebacks_later(PyObject *self,
528 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200529{
530 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
531 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200532 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200533 int repeat = 0;
534 PyObject *file = NULL;
535 int fd;
536 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200537 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200538 char *header;
539 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200540
541 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
542 "d|iOi:dump_tracebacks_later", kwlist,
543 &timeout, &repeat, &file, &exit))
544 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200545 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200546 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
547 return NULL;
548 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200549 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200550 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200551 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
552 return NULL;
553 }
554
Victor Stinnera4de6d82011-04-09 00:47:23 +0200555 tstate = get_thread_state();
556 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200557 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200558
Victor Stinner024e37a2011-03-31 01:31:06 +0200559 file = faulthandler_get_fileno(file, &fd);
560 if (file == NULL)
561 return NULL;
562
Victor Stinnerc790a532011-04-08 13:39:59 +0200563 /* format the timeout */
564 header = format_timeout(timeout);
565 if (header == NULL)
566 return PyErr_NoMemory();
567 header_len = strlen(header);
568
Victor Stinner024e37a2011-03-31 01:31:06 +0200569 /* Cancel previous thread, if running */
Victor Stinnerde10f402011-04-08 12:57:06 +0200570 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200571
572 Py_XDECREF(thread.file);
573 Py_INCREF(file);
574 thread.file = file;
575 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200576 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200577 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200578 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200579 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200580 thread.header = header;
581 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200582
583 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200584 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200585
Victor Stinner024e37a2011-03-31 01:31:06 +0200586 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200587 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200588 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200589 free(header);
590 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200591 PyErr_SetString(PyExc_RuntimeError,
592 "unable to start watchdog thread");
593 return NULL;
594 }
595
596 Py_RETURN_NONE;
597}
598
599static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200600faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200601{
Victor Stinnerde10f402011-04-08 12:57:06 +0200602 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200603 Py_RETURN_NONE;
604}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200605#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200606
Antoine Pitrou75e78b62011-10-04 11:51:23 +0200607#ifdef FAULTHANDLER_WATCHDOG
608
609static void
610file_watchdog(void *unused)
611{
612 PyLockStatus st;
613 PY_TIMEOUT_T timeout;
614
Antoine Pitroub244d072011-10-04 13:00:02 +0200615#define MAXDATA 1024
Antoine Pitrou75e78b62011-10-04 11:51:23 +0200616 char buf1[MAXDATA], buf2[MAXDATA];
617 char *data = buf1, *old_data = buf2;
618 Py_ssize_t data_len, old_data_len = -1;
619
620#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
621 sigset_t set;
622
623 /* we don't want to receive any signal */
624 sigfillset(&set);
625 pthread_sigmask(SIG_SETMASK, &set, NULL);
626#endif
627
628 /* On first pass, feed file contents immediately */
629 timeout = 0;
630 do {
631 st = PyThread_acquire_lock_timed(watchdog.cancel_event,
632 timeout, 0);
633 timeout = watchdog.period_us;
634 if (st == PY_LOCK_ACQUIRED) {
635 PyThread_release_lock(watchdog.cancel_event);
636 break;
637 }
638 /* Timeout => read and write data */
639 assert(st == PY_LOCK_FAILURE);
640
641 if (lseek(watchdog.rfd, 0, SEEK_SET) < 0) {
642 break;
643 }
644 data_len = read(watchdog.rfd, data, MAXDATA);
645 if (data_len < 0) {
646 break;
647 }
648 if (data_len != old_data_len || memcmp(data, old_data, data_len)) {
649 char *tdata;
650 Py_ssize_t tlen;
651 /* Contents changed, feed them to wfd */
652 long x = (long) data_len;
653 /* We can't do anything if the consumer is too slow, just bail out */
654 if (write(watchdog.wfd, (void *) &x, sizeof(x)) < sizeof(x))
655 break;
656 if (write(watchdog.wfd, data, data_len) < data_len)
657 break;
658 tdata = data;
659 data = old_data;
660 old_data = tdata;
661 tlen = data_len;
662 data_len = old_data_len;
663 old_data_len = tlen;
664 }
665 } while (1);
666
667 close(watchdog.rfd);
668 close(watchdog.wfd);
669
670 /* The only way out */
671 PyThread_release_lock(watchdog.running);
Antoine Pitroub244d072011-10-04 13:00:02 +0200672#undef MAXDATA
Antoine Pitrou75e78b62011-10-04 11:51:23 +0200673}
674
675static void
676cancel_file_watchdog(void)
677{
678 /* Notify cancellation */
679 PyThread_release_lock(watchdog.cancel_event);
680
681 /* Wait for thread to join */
682 PyThread_acquire_lock(watchdog.running, 1);
683 PyThread_release_lock(watchdog.running);
684
685 /* The main thread should always hold the cancel_event lock */
686 PyThread_acquire_lock(watchdog.cancel_event, 1);
687}
688
689static PyObject*
690faulthandler_file_watchdog(PyObject *self,
691 PyObject *args, PyObject *kwargs)
692{
693 static char *kwlist[] = {"rfd", "wfd", "period", NULL};
694 double period;
695 PY_TIMEOUT_T period_us;
696 int rfd, wfd;
697
698 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
699 "iid:_file_watchdog", kwlist,
700 &rfd, &wfd, &period))
701 return NULL;
702 if ((period * 1e6) >= (double) PY_TIMEOUT_MAX) {
703 PyErr_SetString(PyExc_OverflowError, "period value is too large");
704 return NULL;
705 }
706 period_us = (PY_TIMEOUT_T)(period * 1e6);
707 if (period_us <= 0) {
708 PyErr_SetString(PyExc_ValueError, "period must be greater than 0");
709 return NULL;
710 }
711
712 /* Cancel previous thread, if running */
713 cancel_file_watchdog();
714
715 watchdog.rfd = rfd;
716 watchdog.wfd = wfd;
717 watchdog.period_us = period_us;
718
719 /* Arm these locks to serve as events when released */
720 PyThread_acquire_lock(watchdog.running, 1);
721
722 if (PyThread_start_new_thread(file_watchdog, NULL) == -1) {
723 PyThread_release_lock(watchdog.running);
724 PyErr_SetString(PyExc_RuntimeError,
725 "unable to start file watchdog thread");
726 return NULL;
727 }
728
729 Py_RETURN_NONE;
730}
731
732static PyObject*
733faulthandler_cancel_file_watchdog(PyObject *self)
734{
735 cancel_file_watchdog();
736 Py_RETURN_NONE;
737}
738#endif /* FAULTHANDLER_WATCHDOG */
739
Victor Stinner024e37a2011-03-31 01:31:06 +0200740#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200741static int
742faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
743{
744#ifdef HAVE_SIGACTION
745 struct sigaction action;
746 action.sa_handler = faulthandler_user;
747 sigemptyset(&action.sa_mask);
748 /* if the signal is received while the kernel is executing a system
749 call, try to restart the system call instead of interrupting it and
750 return EINTR. */
751 action.sa_flags = SA_RESTART;
752 if (chain) {
753 /* do not prevent the signal from being received from within its
754 own signal handler */
755 action.sa_flags = SA_NODEFER;
756 }
757#ifdef HAVE_SIGALTSTACK
758 if (stack.ss_sp != NULL) {
759 /* Call the signal handler on an alternate signal stack
760 provided by sigaltstack() */
761 action.sa_flags |= SA_ONSTACK;
762 }
763#endif
764 return sigaction(signum, &action, p_previous);
765#else
766 _Py_sighandler_t previous;
767 previous = signal(signum, faulthandler_user);
768 if (p_previous != NULL)
769 *p_previous = previous;
770 return (previous == SIG_ERR);
771#endif
772}
773
Victor Stinner024e37a2011-03-31 01:31:06 +0200774/* Handler of user signals (e.g. SIGUSR1).
775
776 Dump the traceback of the current thread, or of all threads if
777 thread.all_threads is true.
778
779 This function is signal safe and should only call signal safe functions. */
780
781static void
782faulthandler_user(int signum)
783{
784 user_signal_t *user;
785 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200786 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200787
788 user = &user_signals[signum];
789 if (!user->enabled)
790 return;
791
Victor Stinnerff4cd882011-04-07 11:50:25 +0200792#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200793 /* PyThreadState_Get() doesn't give the state of the current thread if
794 the thread doesn't hold the GIL. Read the thread local storage (TLS)
795 instead: call PyGILState_GetThisThreadState(). */
796 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200797#else
798 tstate = PyThreadState_Get();
799#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200800
801 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200802 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
803 else {
804 if (tstate == NULL)
805 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200806 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200807 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200808#ifdef HAVE_SIGACTION
809 if (user->chain) {
810 (void)sigaction(signum, &user->previous, NULL);
811 /* call the previous signal handler */
812 raise(signum);
813 (void)faulthandler_register(signum, user->chain, NULL);
814 }
815#else
816 if (user->chain) {
817 /* call the previous signal handler */
818 user->previous(signum);
819 }
820#endif
Victor Stinnerc9256172011-05-07 12:20:11 +0200821 errno = save_errno;
Victor Stinner44378d42011-04-01 15:37:12 +0200822}
823
824static int
825check_signum(int signum)
826{
827 unsigned int i;
828
829 for (i=0; i < faulthandler_nsignals; i++) {
830 if (faulthandler_handlers[i].signum == signum) {
831 PyErr_Format(PyExc_RuntimeError,
832 "signal %i cannot be registered, "
833 "use enable() instead",
834 signum);
835 return 0;
836 }
837 }
838 if (signum < 1 || NSIG <= signum) {
839 PyErr_SetString(PyExc_ValueError, "signal number out of range");
840 return 0;
841 }
842 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200843}
844
845static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200846faulthandler_register_py(PyObject *self,
847 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200848{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200849 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200850 int signum;
851 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200852 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200853 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200854 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200855 user_signal_t *user;
856 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200857 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200858 int err;
859
860 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200861 "i|Oii:register", kwlist,
862 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200863 return NULL;
864
Victor Stinner44378d42011-04-01 15:37:12 +0200865 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200866 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200867
Victor Stinnera4de6d82011-04-09 00:47:23 +0200868 tstate = get_thread_state();
869 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200870 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200871
872 file = faulthandler_get_fileno(file, &fd);
873 if (file == NULL)
874 return NULL;
875
876 if (user_signals == NULL) {
877 user_signals = calloc(NSIG, sizeof(user_signal_t));
878 if (user_signals == NULL)
879 return PyErr_NoMemory();
880 }
881 user = &user_signals[signum];
882
883 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200884 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200885 if (err) {
886 PyErr_SetFromErrno(PyExc_OSError);
887 return NULL;
888 }
889 }
890
891 Py_XDECREF(user->file);
892 Py_INCREF(file);
893 user->file = file;
894 user->fd = fd;
895 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200896 user->chain = chain;
Victor Stinner024e37a2011-03-31 01:31:06 +0200897 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200898 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200899 user->enabled = 1;
900
901 Py_RETURN_NONE;
902}
903
904static int
905faulthandler_unregister(user_signal_t *user, int signum)
906{
Victor Stinnera01ca122011-04-01 12:56:17 +0200907 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200908 return 0;
909 user->enabled = 0;
910#ifdef HAVE_SIGACTION
911 (void)sigaction(signum, &user->previous, NULL);
912#else
913 (void)signal(signum, user->previous);
914#endif
915 Py_CLEAR(user->file);
916 user->fd = -1;
917 return 1;
918}
919
920static PyObject*
921faulthandler_unregister_py(PyObject *self, PyObject *args)
922{
923 int signum;
924 user_signal_t *user;
925 int change;
926
927 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
928 return NULL;
929
Victor Stinner44378d42011-04-01 15:37:12 +0200930 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200931 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200932
Victor Stinnercfa71232011-04-08 12:48:15 +0200933 if (user_signals == NULL)
934 Py_RETURN_FALSE;
935
Victor Stinner024e37a2011-03-31 01:31:06 +0200936 user = &user_signals[signum];
937 change = faulthandler_unregister(user, signum);
938 return PyBool_FromLong(change);
939}
940#endif /* FAULTHANDLER_USER */
941
942
943static PyObject *
944faulthandler_read_null(PyObject *self, PyObject *args)
945{
946 int *x = NULL, y;
947 int release_gil = 0;
948 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
949 return NULL;
950 if (release_gil) {
951 Py_BEGIN_ALLOW_THREADS
952 y = *x;
953 Py_END_ALLOW_THREADS
954 } else
955 y = *x;
956 return PyLong_FromLong(y);
957
958}
959
960static PyObject *
961faulthandler_sigsegv(PyObject *self, PyObject *args)
962{
963#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200964 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
965 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200966 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200967 SIGSEGV was raised by the kernel because of a fault, and so if the
968 program retries to execute the same instruction, the fault will be
969 raised again.
970
971 Here the fault is simulated by a fake SIGSEGV signal raised by the
972 application. We have to raise SIGSEGV at lease twice: once for
973 faulthandler_fatal_error(), and one more time for the previous signal
974 handler. */
975 while(1)
976 raise(SIGSEGV);
977#else
978 raise(SIGSEGV);
979#endif
980 Py_RETURN_NONE;
981}
982
983static PyObject *
984faulthandler_sigfpe(PyObject *self, PyObject *args)
985{
986 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
987 PowerPC. Use volatile to disable compile-time optimizations. */
988 volatile int x = 1, y = 0, z;
989 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +0200990 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
991 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200992 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +0200993 /* This line is never reached, but we pretend to make something with z
994 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +0200995 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +0200996}
997
Victor Stinnerd727e232011-04-01 12:13:55 +0200998static PyObject *
999faulthandler_sigabrt(PyObject *self, PyObject *args)
1000{
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001001#ifdef _MSC_VER
1002 /* Visual Studio: configure abort() to not display an error message nor
1003 open a popup asking to report the fault. */
1004 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
Victor Stinnerd727e232011-04-01 12:13:55 +02001005#endif
Victor Stinner00bc6cc2011-05-10 01:30:03 +02001006 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +02001007 Py_RETURN_NONE;
1008}
1009
Victor Stinner024e37a2011-03-31 01:31:06 +02001010#ifdef SIGBUS
1011static PyObject *
1012faulthandler_sigbus(PyObject *self, PyObject *args)
1013{
1014 raise(SIGBUS);
1015 Py_RETURN_NONE;
1016}
1017#endif
1018
1019#ifdef SIGILL
1020static PyObject *
1021faulthandler_sigill(PyObject *self, PyObject *args)
1022{
Victor Stinner024e37a2011-03-31 01:31:06 +02001023 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +02001024 Py_RETURN_NONE;
1025}
1026#endif
1027
1028static PyObject *
1029faulthandler_fatal_error_py(PyObject *self, PyObject *args)
1030{
1031 char *message;
1032 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
1033 return NULL;
1034 Py_FatalError(message);
1035 Py_RETURN_NONE;
1036}
1037
1038#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner9b493042011-05-23 12:29:10 +02001039static void*
Victor Stinnerf0480752011-03-31 11:34:08 +02001040stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +02001041{
1042 /* allocate 4096 bytes on the stack at each call */
1043 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +02001044 void *sp = &buffer;
1045 *depth += 1;
1046 if (sp < min_sp || max_sp < sp)
1047 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +02001048 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +02001049 buffer[4095] = 0;
1050 return stack_overflow(min_sp, max_sp, depth);
1051}
1052
1053static PyObject *
1054faulthandler_stack_overflow(PyObject *self)
1055{
1056 size_t depth, size;
Victor Stinner425fcd32011-09-07 16:18:56 +02001057 char *sp = (char *)&depth, *stop;
Victor Stinnerf0480752011-03-31 11:34:08 +02001058
1059 depth = 0;
1060 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
1061 sp + STACK_OVERFLOW_MAX_SIZE,
1062 &depth);
1063 if (sp < stop)
1064 size = stop - sp;
1065 else
1066 size = sp - stop;
1067 PyErr_Format(PyExc_RuntimeError,
1068 "unable to raise a stack overflow (allocated %zu bytes "
1069 "on the stack, %zu recursive calls)",
1070 size, depth);
1071 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001072}
1073#endif
1074
1075
1076static int
1077faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
1078{
1079#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +02001080 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001081#endif
1082
1083#ifdef FAULTHANDLER_LATER
1084 Py_VISIT(thread.file);
1085#endif
1086#ifdef FAULTHANDLER_USER
1087 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +02001088 for (signum=0; signum < NSIG; signum++)
1089 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +02001090 }
1091#endif
1092 Py_VISIT(fatal_error.file);
1093 return 0;
1094}
1095
1096PyDoc_STRVAR(module_doc,
1097"faulthandler module.");
1098
1099static PyMethodDef module_methods[] = {
1100 {"enable",
1101 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001102 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001103 "enable the fault handler")},
1104 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
1105 PyDoc_STR("disable(): disable the fault handler")},
1106 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
1107 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
1108 {"dump_traceback",
1109 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +02001110 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001111 "dump the traceback of the current thread, or of all threads "
1112 "if all_threads is True, into file")},
1113#ifdef FAULTHANDLER_LATER
1114 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +02001115 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
1116 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +02001117 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +02001118 "or each timeout seconds if repeat is True. If exit is True, "
1119 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001120 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +02001121 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +02001122 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
1123 "to dump_tracebacks_later().")},
1124#endif
1125
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001126#ifdef FAULTHANDLER_WATCHDOG
1127 {"_file_watchdog",
1128 (PyCFunction)faulthandler_file_watchdog, METH_VARARGS|METH_KEYWORDS,
1129 PyDoc_STR("_file_watchdog(rfd, wfd, period):\n"
1130 "feed the contents of 'rfd' to 'wfd', if changed,\n"
1131 "every 'period seconds'.")},
1132 {"_cancel_file_watchdog",
1133 (PyCFunction)faulthandler_cancel_file_watchdog, METH_NOARGS,
1134 PyDoc_STR("_cancel_file_watchdog():\ncancel the previous call "
1135 "to _file_watchdog().")},
1136#endif
1137
Victor Stinner024e37a2011-03-31 01:31:06 +02001138#ifdef FAULTHANDLER_USER
1139 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +02001140 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
1141 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Victor Stinner024e37a2011-03-31 01:31:06 +02001142 "register an handler for the signal 'signum': dump the "
1143 "traceback of the current thread, or of all threads if "
1144 "all_threads is True, into file")},
1145 {"unregister",
1146 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
1147 PyDoc_STR("unregister(signum): unregister the handler of the signal "
1148 "'signum' registered by register()")},
1149#endif
1150
1151 {"_read_null", faulthandler_read_null, METH_VARARGS,
1152 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
1153 "a SIGSEGV or SIGBUS signal depending on the platform")},
1154 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
1155 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +02001156 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
1157 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001158 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1159 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
1160#ifdef SIGBUS
1161 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
1162 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
1163#endif
1164#ifdef SIGILL
1165 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
1166 PyDoc_STR("_sigill(): raise a SIGILL signal")},
1167#endif
1168 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1169 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
1170#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1171 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1172 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1173#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001174 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001175};
1176
1177static struct PyModuleDef module_def = {
1178 PyModuleDef_HEAD_INIT,
1179 "faulthandler",
1180 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001181 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001182 module_methods,
1183 NULL,
1184 faulthandler_traverse,
1185 NULL,
1186 NULL
1187};
1188
1189PyMODINIT_FUNC
1190PyInit_faulthandler(void)
1191{
1192 return PyModule_Create(&module_def);
1193}
1194
Victor Stinner410dd7d2011-05-11 20:56:08 +02001195/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1196 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001197
1198static int
1199faulthandler_env_options(void)
1200{
1201 PyObject *xoptions, *key, *module, *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001202 _Py_IDENTIFIER(enable);
Victor Stinner024e37a2011-03-31 01:31:06 +02001203
1204 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
Victor Stinner25095b22011-05-26 13:47:08 +02001205 int has_key;
1206
Victor Stinner024e37a2011-03-31 01:31:06 +02001207 xoptions = PySys_GetXOptions();
1208 if (xoptions == NULL)
1209 return -1;
1210
1211 key = PyUnicode_FromString("faulthandler");
1212 if (key == NULL)
1213 return -1;
1214
Victor Stinner25095b22011-05-26 13:47:08 +02001215 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001216 Py_DECREF(key);
Victor Stinner25095b22011-05-26 13:47:08 +02001217 if (!has_key)
Victor Stinner024e37a2011-03-31 01:31:06 +02001218 return 0;
1219 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001220
1221 module = PyImport_ImportModule("faulthandler");
1222 if (module == NULL) {
1223 return -1;
1224 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001225 res = _PyObject_CallMethodId(module, &PyId_enable, "");
Victor Stinner024e37a2011-03-31 01:31:06 +02001226 Py_DECREF(module);
1227 if (res == NULL)
1228 return -1;
1229 Py_DECREF(res);
1230 return 0;
1231}
1232
1233int _PyFaulthandler_Init(void)
1234{
1235#ifdef HAVE_SIGALTSTACK
1236 int err;
1237
1238 /* Try to allocate an alternate stack for faulthandler() signal handler to
1239 * be able to allocate memory on the stack, even on a stack overflow. If it
1240 * fails, ignore the error. */
1241 stack.ss_flags = 0;
1242 stack.ss_size = SIGSTKSZ;
1243 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1244 if (stack.ss_sp != NULL) {
1245 err = sigaltstack(&stack, NULL);
1246 if (err) {
1247 PyMem_Free(stack.ss_sp);
1248 stack.ss_sp = NULL;
1249 }
1250 }
1251#endif
1252#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001253 thread.file = NULL;
1254 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001255 thread.running = PyThread_allocate_lock();
1256 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001257 PyErr_SetString(PyExc_RuntimeError,
1258 "could not allocate locks for faulthandler");
1259 return -1;
1260 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001261 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001262#endif
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001263#ifdef FAULTHANDLER_WATCHDOG
1264 watchdog.cancel_event = PyThread_allocate_lock();
1265 watchdog.running = PyThread_allocate_lock();
1266 if (!watchdog.cancel_event || !watchdog.running) {
1267 PyErr_SetString(PyExc_RuntimeError,
1268 "could not allocate locks for faulthandler");
1269 return -1;
1270 }
1271 PyThread_acquire_lock(watchdog.cancel_event, 1);
1272#endif
Victor Stinner024e37a2011-03-31 01:31:06 +02001273
1274 return faulthandler_env_options();
1275}
1276
1277void _PyFaulthandler_Fini(void)
1278{
1279#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001280 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001281#endif
1282
1283#ifdef FAULTHANDLER_LATER
1284 /* later */
Victor Stinnerde10f402011-04-08 12:57:06 +02001285 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001286 if (thread.cancel_event) {
Victor Stinnerde10f402011-04-08 12:57:06 +02001287 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001288 PyThread_free_lock(thread.cancel_event);
1289 thread.cancel_event = NULL;
1290 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001291 if (thread.running) {
1292 PyThread_free_lock(thread.running);
1293 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001294 }
1295#endif
1296
Antoine Pitrou75e78b62011-10-04 11:51:23 +02001297#ifdef FAULTHANDLER_WATCHDOG
1298 /* file watchdog */
1299 cancel_file_watchdog();
1300 if (watchdog.cancel_event) {
1301 PyThread_release_lock(watchdog.cancel_event);
1302 PyThread_free_lock(watchdog.cancel_event);
1303 watchdog.cancel_event = NULL;
1304 }
1305 if (watchdog.running) {
1306 PyThread_free_lock(watchdog.running);
1307 watchdog.running = NULL;
1308 }
1309#endif
1310
Victor Stinner024e37a2011-03-31 01:31:06 +02001311#ifdef FAULTHANDLER_USER
1312 /* user */
1313 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001314 for (signum=0; signum < NSIG; signum++)
1315 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001316 free(user_signals);
1317 user_signals = NULL;
1318 }
1319#endif
1320
1321 /* fatal */
1322 faulthandler_disable();
1323#ifdef HAVE_SIGALTSTACK
1324 if (stack.ss_sp != NULL) {
1325 PyMem_Free(stack.ss_sp);
1326 stack.ss_sp = NULL;
1327 }
1328#endif
1329}