blob: 8ee063054436af07f98af372775064ba98ac98c7 [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
16#endif
17
18#ifndef MS_WINDOWS
Victor Stinnerd727e232011-04-01 12:13:55 +020019 /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
20 SIGILL can be handled by the process, and these signals can only be used
21 with enable(), not using register() */
Victor Stinner024e37a2011-03-31 01:31:06 +020022# define FAULTHANDLER_USER
23#endif
24
25#define PUTS(fd, str) write(fd, str, strlen(str))
26
27#ifdef HAVE_SIGACTION
28typedef struct sigaction _Py_sighandler_t;
29#else
30typedef PyOS_sighandler_t _Py_sighandler_t;
31#endif
32
33typedef struct {
34 int signum;
35 int enabled;
36 const char* name;
37 _Py_sighandler_t previous;
38 int all_threads;
39} fault_handler_t;
40
41static struct {
42 int enabled;
43 PyObject *file;
44 int fd;
45 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020046 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020047} fatal_error = {0, NULL, -1, 0};
48
49#ifdef FAULTHANDLER_LATER
50static struct {
51 PyObject *file;
52 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020053 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020054 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020055 PyInterpreterState *interp;
56 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020057 char *header;
58 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020059 /* The main thread always holds this lock. It is only released when
60 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020061 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020062 PyThread_type_lock cancel_event;
63 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020064 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020065} thread;
66#endif
67
68#ifdef FAULTHANDLER_USER
69typedef struct {
70 int enabled;
71 PyObject *file;
72 int fd;
73 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020074 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020075 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020076 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020077} user_signal_t;
78
79static user_signal_t *user_signals;
80
81/* the following macros come from Python: Modules/signalmodule.c */
82#if defined(PYOS_OS2) && !defined(PYCC_GCC)
83#define NSIG 12
84#endif
85#ifndef NSIG
86# if defined(_NSIG)
87# define NSIG _NSIG /* For BSD/SysV */
88# elif defined(_SIGMAX)
89# define NSIG (_SIGMAX + 1) /* For QNX */
90# elif defined(SIGMAX)
91# define NSIG (SIGMAX + 1) /* For djgpp */
92# else
93# define NSIG 64 /* Use a reasonable default value */
94# endif
95#endif
96
Victor Stinnera9a9dab2011-07-13 23:39:53 +020097static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +020098#endif /* FAULTHANDLER_USER */
99
100
101static fault_handler_t faulthandler_handlers[] = {
102#ifdef SIGBUS
103 {SIGBUS, 0, "Bus error", },
104#endif
105#ifdef SIGILL
106 {SIGILL, 0, "Illegal instruction", },
107#endif
108 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200109 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200110 /* define SIGSEGV at the end to make it the default choice if searching the
111 handler fails in faulthandler_fatal_error() */
112 {SIGSEGV, 0, "Segmentation fault", }
113};
114static const unsigned char faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200115 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200116
117#ifdef HAVE_SIGALTSTACK
118static stack_t stack;
119#endif
120
121
122/* Get the file descriptor of a file by calling its fileno() method and then
123 call its flush() method.
124
125 If file is NULL or Py_None, use sys.stderr as the new file.
126
127 On success, return the new file and write the file descriptor into *p_fd.
128 On error, return NULL. */
129
130static PyObject*
131faulthandler_get_fileno(PyObject *file, int *p_fd)
132{
133 PyObject *result;
134 long fd_long;
135 int fd;
136
137 if (file == NULL || file == Py_None) {
138 file = PySys_GetObject("stderr");
139 if (file == NULL) {
140 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
141 return NULL;
142 }
143 }
144
145 result = PyObject_CallMethod(file, "fileno", "");
146 if (result == NULL)
147 return NULL;
148
149 fd = -1;
150 if (PyLong_Check(result)) {
151 fd_long = PyLong_AsLong(result);
152 if (0 <= fd_long && fd_long < INT_MAX)
153 fd = (int)fd_long;
154 }
155 Py_DECREF(result);
156
157 if (fd == -1) {
158 PyErr_SetString(PyExc_RuntimeError,
159 "file.fileno() is not a valid file descriptor");
160 return NULL;
161 }
162
163 result = PyObject_CallMethod(file, "flush", "");
164 if (result != NULL)
165 Py_DECREF(result);
166 else {
167 /* ignore flush() error */
168 PyErr_Clear();
169 }
170 *p_fd = fd;
171 return file;
172}
173
Victor Stinnera4de6d82011-04-09 00:47:23 +0200174/* Get the state of the current thread: only call this function if the current
175 thread holds the GIL. Raise an exception on error. */
176static PyThreadState*
177get_thread_state(void)
178{
179 PyThreadState *tstate = PyThreadState_Get();
180 if (tstate == NULL) {
181 PyErr_SetString(PyExc_RuntimeError,
182 "unable to get the current thread state");
183 return NULL;
184 }
185 return tstate;
186}
187
Victor Stinner024e37a2011-03-31 01:31:06 +0200188static PyObject*
189faulthandler_dump_traceback_py(PyObject *self,
190 PyObject *args, PyObject *kwargs)
191{
192 static char *kwlist[] = {"file", "all_threads", NULL};
193 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200194 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200195 PyThreadState *tstate;
196 const char *errmsg;
197 int fd;
198
199 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
200 "|Oi:dump_traceback", kwlist,
201 &file, &all_threads))
202 return NULL;
203
204 file = faulthandler_get_fileno(file, &fd);
205 if (file == NULL)
206 return NULL;
207
Victor Stinnera4de6d82011-04-09 00:47:23 +0200208 tstate = get_thread_state();
209 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200210 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200211
212 if (all_threads) {
213 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
214 if (errmsg != NULL) {
215 PyErr_SetString(PyExc_RuntimeError, errmsg);
216 return NULL;
217 }
218 }
219 else {
220 _Py_DumpTraceback(fd, tstate);
221 }
222 Py_RETURN_NONE;
223}
224
225
Victor Stinner410dd7d2011-05-11 20:56:08 +0200226/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200227
228 Display the current Python traceback, restore the previous handler and call
229 the previous handler.
230
Victor Stinner410dd7d2011-05-11 20:56:08 +0200231 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200232 signal handler would not be called (for an unknown reason). The execution of
233 the program continues at faulthandler_fatal_error() exit, but the same
234 instruction will raise the same fault (signal), and so the previous handler
235 will be called.
236
Victor Stinner410dd7d2011-05-11 20:56:08 +0200237 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200238
239static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200240faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200241{
242 const int fd = fatal_error.fd;
243 unsigned int i;
244 fault_handler_t *handler = NULL;
245 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200246 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200247
248 if (!fatal_error.enabled)
249 return;
250
251 for (i=0; i < faulthandler_nsignals; i++) {
252 handler = &faulthandler_handlers[i];
253 if (handler->signum == signum)
254 break;
255 }
256 if (handler == NULL) {
257 /* faulthandler_nsignals == 0 (unlikely) */
258 return;
259 }
260
261 /* restore the previous handler */
262#ifdef HAVE_SIGACTION
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200263 (void)sigaction(signum, &handler->previous, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200264#else
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200265 (void)signal(signum, handler->previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200266#endif
267 handler->enabled = 0;
268
269 PUTS(fd, "Fatal Python error: ");
270 PUTS(fd, handler->name);
271 PUTS(fd, "\n\n");
272
Victor Stinnerff4cd882011-04-07 11:50:25 +0200273#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200274 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
Victor Stinner410dd7d2011-05-11 20:56:08 +0200275 are thus delivered to the thread that caused the fault. Get the Python
Victor Stinnerd727e232011-04-01 12:13:55 +0200276 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200277
278 PyThreadState_Get() doesn't give the state of the thread that caused the
279 fault if the thread released the GIL, and so this function cannot be
280 used. Read the thread local storage (TLS) instead: call
281 PyGILState_GetThisThreadState(). */
282 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200283#else
284 tstate = PyThreadState_Get();
285#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200286
287 if (fatal_error.all_threads)
Victor Stinnera4de6d82011-04-09 00:47:23 +0200288 _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate);
289 else {
290 if (tstate != NULL)
291 _Py_DumpTraceback(fd, tstate);
292 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200293
Victor Stinnerc9256172011-05-07 12:20:11 +0200294 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200295#ifdef MS_WINDOWS
296 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200297 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200298 handler, because the Windows signal handler would not be called */
299 return;
300 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200301#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200302 /* call the previous signal handler: it is called immediatly if we use
303 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
304 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200305}
306
Victor Stinnerd727e232011-04-01 12:13:55 +0200307/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200308
309static PyObject*
310faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
311{
312 static char *kwlist[] = {"file", "all_threads", NULL};
313 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200314 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200315 unsigned int i;
316 fault_handler_t *handler;
317#ifdef HAVE_SIGACTION
318 struct sigaction action;
319#endif
320 int err;
321 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200322 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200323
324 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
325 "|Oi:enable", kwlist, &file, &all_threads))
326 return NULL;
327
328 file = faulthandler_get_fileno(file, &fd);
329 if (file == NULL)
330 return NULL;
331
Victor Stinnera4de6d82011-04-09 00:47:23 +0200332 tstate = get_thread_state();
333 if (tstate == NULL)
334 return NULL;
335
Victor Stinner024e37a2011-03-31 01:31:06 +0200336 Py_XDECREF(fatal_error.file);
337 Py_INCREF(file);
338 fatal_error.file = file;
339 fatal_error.fd = fd;
340 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200341 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200342
343 if (!fatal_error.enabled) {
344 fatal_error.enabled = 1;
345
346 for (i=0; i < faulthandler_nsignals; i++) {
347 handler = &faulthandler_handlers[i];
348#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200349 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200350 sigemptyset(&action.sa_mask);
351 /* Do not prevent the signal from being received from within
352 its own signal handler */
353 action.sa_flags = SA_NODEFER;
354#ifdef HAVE_SIGALTSTACK
355 if (stack.ss_sp != NULL) {
356 /* Call the signal handler on an alternate signal stack
357 provided by sigaltstack() */
358 action.sa_flags |= SA_ONSTACK;
359 }
360#endif
361 err = sigaction(handler->signum, &action, &handler->previous);
362#else
363 handler->previous = signal(handler->signum,
364 faulthandler_fatal_error);
365 err = (handler->previous == SIG_ERR);
366#endif
367 if (err) {
368 PyErr_SetFromErrno(PyExc_RuntimeError);
369 return NULL;
370 }
371 handler->enabled = 1;
372 }
373 }
374 Py_RETURN_NONE;
375}
376
377static void
378faulthandler_disable(void)
379{
380 unsigned int i;
381 fault_handler_t *handler;
382
383 if (fatal_error.enabled) {
384 fatal_error.enabled = 0;
385 for (i=0; i < faulthandler_nsignals; i++) {
386 handler = &faulthandler_handlers[i];
387 if (!handler->enabled)
388 continue;
389#ifdef HAVE_SIGACTION
390 (void)sigaction(handler->signum, &handler->previous, NULL);
391#else
392 (void)signal(handler->signum, handler->previous);
393#endif
394 handler->enabled = 0;
395 }
396 }
397
398 Py_CLEAR(fatal_error.file);
399}
400
401static PyObject*
402faulthandler_disable_py(PyObject *self)
403{
404 if (!fatal_error.enabled) {
405 Py_INCREF(Py_False);
406 return Py_False;
407 }
408 faulthandler_disable();
409 Py_INCREF(Py_True);
410 return Py_True;
411}
412
413static PyObject*
414faulthandler_is_enabled(PyObject *self)
415{
416 return PyBool_FromLong(fatal_error.enabled);
417}
418
419#ifdef FAULTHANDLER_LATER
420
421static void
422faulthandler_thread(void *unused)
423{
424 PyLockStatus st;
425 const char* errmsg;
426 PyThreadState *current;
427 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200428#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200429 sigset_t set;
430
431 /* we don't want to receive any signal */
432 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200433 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200434#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200435
436 do {
437 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200438 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200439 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200440 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200441 break;
442 }
443 /* Timeout => dump traceback */
444 assert(st == PY_LOCK_FAILURE);
445
446 /* get the thread holding the GIL, NULL if no thread hold the GIL */
447 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
448
Victor Stinnerc790a532011-04-08 13:39:59 +0200449 write(thread.fd, thread.header, thread.header_len);
450
Victor Stinner024e37a2011-03-31 01:31:06 +0200451 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
452 ok = (errmsg == NULL);
453
454 if (thread.exit)
455 _exit(1);
456 } while (ok && thread.repeat);
457
458 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200459 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200460}
461
462static void
Victor Stinnerde10f402011-04-08 12:57:06 +0200463cancel_dump_tracebacks_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200464{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200465 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200466 PyThread_release_lock(thread.cancel_event);
467
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200468 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200469 PyThread_acquire_lock(thread.running, 1);
470 PyThread_release_lock(thread.running);
471
472 /* The main thread should always hold the cancel_event lock */
473 PyThread_acquire_lock(thread.cancel_event, 1);
474
Victor Stinner024e37a2011-03-31 01:31:06 +0200475 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200476 if (thread.header) {
477 free(thread.header);
478 thread.header = NULL;
479 }
480}
481
482static char*
483format_timeout(double timeout)
484{
485 unsigned long us, sec, min, hour;
486 double intpart, fracpart;
487 char buffer[100];
488
489 fracpart = modf(timeout, &intpart);
490 sec = (unsigned long)intpart;
491 us = (unsigned long)(fracpart * 1e6);
492 min = sec / 60;
493 sec %= 60;
494 hour = min / 60;
495 min %= 60;
496
497 if (us != 0)
498 PyOS_snprintf(buffer, sizeof(buffer),
499 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
500 hour, min, sec, us);
501 else
502 PyOS_snprintf(buffer, sizeof(buffer),
503 "Timeout (%lu:%02lu:%02lu)!\n",
504 hour, min, sec);
505
506 return strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200507}
508
509static PyObject*
Victor Stinner96994402011-04-07 11:37:19 +0200510faulthandler_dump_tracebacks_later(PyObject *self,
511 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200512{
513 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
514 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200515 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200516 int repeat = 0;
517 PyObject *file = NULL;
518 int fd;
519 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200520 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200521 char *header;
522 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200523
524 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
525 "d|iOi:dump_tracebacks_later", kwlist,
526 &timeout, &repeat, &file, &exit))
527 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200528 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200529 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
530 return NULL;
531 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200532 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200533 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200534 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
535 return NULL;
536 }
537
Victor Stinnera4de6d82011-04-09 00:47:23 +0200538 tstate = get_thread_state();
539 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200540 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200541
Victor Stinner024e37a2011-03-31 01:31:06 +0200542 file = faulthandler_get_fileno(file, &fd);
543 if (file == NULL)
544 return NULL;
545
Victor Stinnerc790a532011-04-08 13:39:59 +0200546 /* format the timeout */
547 header = format_timeout(timeout);
548 if (header == NULL)
549 return PyErr_NoMemory();
550 header_len = strlen(header);
551
Victor Stinner024e37a2011-03-31 01:31:06 +0200552 /* Cancel previous thread, if running */
Victor Stinnerde10f402011-04-08 12:57:06 +0200553 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200554
555 Py_XDECREF(thread.file);
556 Py_INCREF(file);
557 thread.file = file;
558 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200559 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200560 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200561 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200562 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200563 thread.header = header;
564 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200565
566 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200567 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200568
Victor Stinner024e37a2011-03-31 01:31:06 +0200569 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200570 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200571 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200572 free(header);
573 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200574 PyErr_SetString(PyExc_RuntimeError,
575 "unable to start watchdog thread");
576 return NULL;
577 }
578
579 Py_RETURN_NONE;
580}
581
582static PyObject*
Victor Stinner702624e2011-03-31 03:42:34 +0200583faulthandler_cancel_dump_tracebacks_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200584{
Victor Stinnerde10f402011-04-08 12:57:06 +0200585 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200586 Py_RETURN_NONE;
587}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200588#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200589
590#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200591static int
592faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
593{
594#ifdef HAVE_SIGACTION
595 struct sigaction action;
596 action.sa_handler = faulthandler_user;
597 sigemptyset(&action.sa_mask);
598 /* if the signal is received while the kernel is executing a system
599 call, try to restart the system call instead of interrupting it and
600 return EINTR. */
601 action.sa_flags = SA_RESTART;
602 if (chain) {
603 /* do not prevent the signal from being received from within its
604 own signal handler */
605 action.sa_flags = SA_NODEFER;
606 }
607#ifdef HAVE_SIGALTSTACK
608 if (stack.ss_sp != NULL) {
609 /* Call the signal handler on an alternate signal stack
610 provided by sigaltstack() */
611 action.sa_flags |= SA_ONSTACK;
612 }
613#endif
614 return sigaction(signum, &action, p_previous);
615#else
616 _Py_sighandler_t previous;
617 previous = signal(signum, faulthandler_user);
618 if (p_previous != NULL)
619 *p_previous = previous;
620 return (previous == SIG_ERR);
621#endif
622}
623
Victor Stinner024e37a2011-03-31 01:31:06 +0200624/* Handler of user signals (e.g. SIGUSR1).
625
626 Dump the traceback of the current thread, or of all threads if
627 thread.all_threads is true.
628
629 This function is signal safe and should only call signal safe functions. */
630
631static void
632faulthandler_user(int signum)
633{
634 user_signal_t *user;
635 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200636 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200637
638 user = &user_signals[signum];
639 if (!user->enabled)
640 return;
641
Victor Stinnerff4cd882011-04-07 11:50:25 +0200642#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200643 /* PyThreadState_Get() doesn't give the state of the current thread if
644 the thread doesn't hold the GIL. Read the thread local storage (TLS)
645 instead: call PyGILState_GetThisThreadState(). */
646 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200647#else
648 tstate = PyThreadState_Get();
649#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200650
651 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200652 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
653 else {
654 if (tstate == NULL)
655 return;
Victor Stinner024e37a2011-03-31 01:31:06 +0200656 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200657 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200658#ifdef HAVE_SIGACTION
659 if (user->chain) {
660 (void)sigaction(signum, &user->previous, NULL);
661 /* call the previous signal handler */
662 raise(signum);
663 (void)faulthandler_register(signum, user->chain, NULL);
664 }
665#else
666 if (user->chain) {
667 /* call the previous signal handler */
668 user->previous(signum);
669 }
670#endif
Victor Stinnerc9256172011-05-07 12:20:11 +0200671 errno = save_errno;
Victor Stinner44378d42011-04-01 15:37:12 +0200672}
673
674static int
675check_signum(int signum)
676{
677 unsigned int i;
678
679 for (i=0; i < faulthandler_nsignals; i++) {
680 if (faulthandler_handlers[i].signum == signum) {
681 PyErr_Format(PyExc_RuntimeError,
682 "signal %i cannot be registered, "
683 "use enable() instead",
684 signum);
685 return 0;
686 }
687 }
688 if (signum < 1 || NSIG <= signum) {
689 PyErr_SetString(PyExc_ValueError, "signal number out of range");
690 return 0;
691 }
692 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200693}
694
695static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200696faulthandler_register_py(PyObject *self,
697 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200698{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200699 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200700 int signum;
701 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200702 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200703 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200704 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200705 user_signal_t *user;
706 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200707 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200708 int err;
709
710 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200711 "i|Oii:register", kwlist,
712 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200713 return NULL;
714
Victor Stinner44378d42011-04-01 15:37:12 +0200715 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200716 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200717
Victor Stinnera4de6d82011-04-09 00:47:23 +0200718 tstate = get_thread_state();
719 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200720 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200721
722 file = faulthandler_get_fileno(file, &fd);
723 if (file == NULL)
724 return NULL;
725
726 if (user_signals == NULL) {
727 user_signals = calloc(NSIG, sizeof(user_signal_t));
728 if (user_signals == NULL)
729 return PyErr_NoMemory();
730 }
731 user = &user_signals[signum];
732
733 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200734 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200735 if (err) {
736 PyErr_SetFromErrno(PyExc_OSError);
737 return NULL;
738 }
739 }
740
741 Py_XDECREF(user->file);
742 Py_INCREF(file);
743 user->file = file;
744 user->fd = fd;
745 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200746 user->chain = chain;
Victor Stinner024e37a2011-03-31 01:31:06 +0200747 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200748 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200749 user->enabled = 1;
750
751 Py_RETURN_NONE;
752}
753
754static int
755faulthandler_unregister(user_signal_t *user, int signum)
756{
Victor Stinnera01ca122011-04-01 12:56:17 +0200757 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200758 return 0;
759 user->enabled = 0;
760#ifdef HAVE_SIGACTION
761 (void)sigaction(signum, &user->previous, NULL);
762#else
763 (void)signal(signum, user->previous);
764#endif
765 Py_CLEAR(user->file);
766 user->fd = -1;
767 return 1;
768}
769
770static PyObject*
771faulthandler_unregister_py(PyObject *self, PyObject *args)
772{
773 int signum;
774 user_signal_t *user;
775 int change;
776
777 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
778 return NULL;
779
Victor Stinner44378d42011-04-01 15:37:12 +0200780 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200781 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200782
Victor Stinnercfa71232011-04-08 12:48:15 +0200783 if (user_signals == NULL)
784 Py_RETURN_FALSE;
785
Victor Stinner024e37a2011-03-31 01:31:06 +0200786 user = &user_signals[signum];
787 change = faulthandler_unregister(user, signum);
788 return PyBool_FromLong(change);
789}
790#endif /* FAULTHANDLER_USER */
791
792
793static PyObject *
794faulthandler_read_null(PyObject *self, PyObject *args)
795{
796 int *x = NULL, y;
797 int release_gil = 0;
798 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
799 return NULL;
800 if (release_gil) {
801 Py_BEGIN_ALLOW_THREADS
802 y = *x;
803 Py_END_ALLOW_THREADS
804 } else
805 y = *x;
806 return PyLong_FromLong(y);
807
808}
809
810static PyObject *
811faulthandler_sigsegv(PyObject *self, PyObject *args)
812{
813#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200814 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
815 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200816 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200817 SIGSEGV was raised by the kernel because of a fault, and so if the
818 program retries to execute the same instruction, the fault will be
819 raised again.
820
821 Here the fault is simulated by a fake SIGSEGV signal raised by the
822 application. We have to raise SIGSEGV at lease twice: once for
823 faulthandler_fatal_error(), and one more time for the previous signal
824 handler. */
825 while(1)
826 raise(SIGSEGV);
827#else
828 raise(SIGSEGV);
829#endif
830 Py_RETURN_NONE;
831}
832
833static PyObject *
834faulthandler_sigfpe(PyObject *self, PyObject *args)
835{
836 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
837 PowerPC. Use volatile to disable compile-time optimizations. */
838 volatile int x = 1, y = 0, z;
839 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +0200840 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
841 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200842 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +0200843 /* This line is never reached, but we pretend to make something with z
844 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +0200845 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +0200846}
847
Victor Stinnerd727e232011-04-01 12:13:55 +0200848static PyObject *
849faulthandler_sigabrt(PyObject *self, PyObject *args)
850{
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200851#ifdef _MSC_VER
852 /* Visual Studio: configure abort() to not display an error message nor
853 open a popup asking to report the fault. */
854 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
Victor Stinnerd727e232011-04-01 12:13:55 +0200855#endif
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200856 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +0200857 Py_RETURN_NONE;
858}
859
Victor Stinner024e37a2011-03-31 01:31:06 +0200860#ifdef SIGBUS
861static PyObject *
862faulthandler_sigbus(PyObject *self, PyObject *args)
863{
864 raise(SIGBUS);
865 Py_RETURN_NONE;
866}
867#endif
868
869#ifdef SIGILL
870static PyObject *
871faulthandler_sigill(PyObject *self, PyObject *args)
872{
Victor Stinner024e37a2011-03-31 01:31:06 +0200873 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200874 Py_RETURN_NONE;
875}
876#endif
877
878static PyObject *
879faulthandler_fatal_error_py(PyObject *self, PyObject *args)
880{
881 char *message;
882 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
883 return NULL;
884 Py_FatalError(message);
885 Py_RETURN_NONE;
886}
887
888#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner9b493042011-05-23 12:29:10 +0200889static void*
Victor Stinnerf0480752011-03-31 11:34:08 +0200890stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200891{
892 /* allocate 4096 bytes on the stack at each call */
893 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200894 void *sp = &buffer;
895 *depth += 1;
896 if (sp < min_sp || max_sp < sp)
897 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200898 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200899 buffer[4095] = 0;
900 return stack_overflow(min_sp, max_sp, depth);
901}
902
903static PyObject *
904faulthandler_stack_overflow(PyObject *self)
905{
906 size_t depth, size;
Victor Stinner425fcd32011-09-07 16:18:56 +0200907 char *sp = (char *)&depth, *stop;
Victor Stinnerf0480752011-03-31 11:34:08 +0200908
909 depth = 0;
910 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
911 sp + STACK_OVERFLOW_MAX_SIZE,
912 &depth);
913 if (sp < stop)
914 size = stop - sp;
915 else
916 size = sp - stop;
917 PyErr_Format(PyExc_RuntimeError,
918 "unable to raise a stack overflow (allocated %zu bytes "
919 "on the stack, %zu recursive calls)",
920 size, depth);
921 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200922}
923#endif
924
925
926static int
927faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
928{
929#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200930 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200931#endif
932
933#ifdef FAULTHANDLER_LATER
934 Py_VISIT(thread.file);
935#endif
936#ifdef FAULTHANDLER_USER
937 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200938 for (signum=0; signum < NSIG; signum++)
939 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200940 }
941#endif
942 Py_VISIT(fatal_error.file);
943 return 0;
944}
945
946PyDoc_STRVAR(module_doc,
947"faulthandler module.");
948
949static PyMethodDef module_methods[] = {
950 {"enable",
951 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +0200952 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200953 "enable the fault handler")},
954 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
955 PyDoc_STR("disable(): disable the fault handler")},
956 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
957 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
958 {"dump_traceback",
959 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +0200960 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200961 "dump the traceback of the current thread, or of all threads "
962 "if all_threads is True, into file")},
963#ifdef FAULTHANDLER_LATER
964 {"dump_tracebacks_later",
Victor Stinner96994402011-04-07 11:37:19 +0200965 (PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
966 PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200967 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200968 "or each timeout seconds if repeat is True. If exit is True, "
969 "call _exit(1) which is not safe.")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200970 {"cancel_dump_tracebacks_later",
Victor Stinner702624e2011-03-31 03:42:34 +0200971 (PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
Victor Stinner024e37a2011-03-31 01:31:06 +0200972 PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "
973 "to dump_tracebacks_later().")},
974#endif
975
976#ifdef FAULTHANDLER_USER
977 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200978 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
979 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200980 "register an handler for the signal 'signum': dump the "
981 "traceback of the current thread, or of all threads if "
982 "all_threads is True, into file")},
983 {"unregister",
984 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
985 PyDoc_STR("unregister(signum): unregister the handler of the signal "
986 "'signum' registered by register()")},
987#endif
988
989 {"_read_null", faulthandler_read_null, METH_VARARGS,
990 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
991 "a SIGSEGV or SIGBUS signal depending on the platform")},
992 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
993 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +0200994 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
995 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200996 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
997 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
998#ifdef SIGBUS
999 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
1000 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
1001#endif
1002#ifdef SIGILL
1003 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
1004 PyDoc_STR("_sigill(): raise a SIGILL signal")},
1005#endif
1006 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1007 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
1008#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1009 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1010 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1011#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001012 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001013};
1014
1015static struct PyModuleDef module_def = {
1016 PyModuleDef_HEAD_INIT,
1017 "faulthandler",
1018 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001019 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001020 module_methods,
1021 NULL,
1022 faulthandler_traverse,
1023 NULL,
1024 NULL
1025};
1026
1027PyMODINIT_FUNC
1028PyInit_faulthandler(void)
1029{
1030 return PyModule_Create(&module_def);
1031}
1032
Victor Stinner410dd7d2011-05-11 20:56:08 +02001033/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1034 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001035
1036static int
1037faulthandler_env_options(void)
1038{
1039 PyObject *xoptions, *key, *module, *res;
Victor Stinner024e37a2011-03-31 01:31:06 +02001040
1041 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
Victor Stinner25095b22011-05-26 13:47:08 +02001042 int has_key;
1043
Victor Stinner024e37a2011-03-31 01:31:06 +02001044 xoptions = PySys_GetXOptions();
1045 if (xoptions == NULL)
1046 return -1;
1047
1048 key = PyUnicode_FromString("faulthandler");
1049 if (key == NULL)
1050 return -1;
1051
Victor Stinner25095b22011-05-26 13:47:08 +02001052 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001053 Py_DECREF(key);
Victor Stinner25095b22011-05-26 13:47:08 +02001054 if (!has_key)
Victor Stinner024e37a2011-03-31 01:31:06 +02001055 return 0;
1056 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001057
1058 module = PyImport_ImportModule("faulthandler");
1059 if (module == NULL) {
1060 return -1;
1061 }
1062 res = PyObject_CallMethod(module, "enable", "");
1063 Py_DECREF(module);
1064 if (res == NULL)
1065 return -1;
1066 Py_DECREF(res);
1067 return 0;
1068}
1069
1070int _PyFaulthandler_Init(void)
1071{
1072#ifdef HAVE_SIGALTSTACK
1073 int err;
1074
1075 /* Try to allocate an alternate stack for faulthandler() signal handler to
1076 * be able to allocate memory on the stack, even on a stack overflow. If it
1077 * fails, ignore the error. */
1078 stack.ss_flags = 0;
1079 stack.ss_size = SIGSTKSZ;
1080 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1081 if (stack.ss_sp != NULL) {
1082 err = sigaltstack(&stack, NULL);
1083 if (err) {
1084 PyMem_Free(stack.ss_sp);
1085 stack.ss_sp = NULL;
1086 }
1087 }
1088#endif
1089#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001090 thread.file = NULL;
1091 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001092 thread.running = PyThread_allocate_lock();
1093 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001094 PyErr_SetString(PyExc_RuntimeError,
1095 "could not allocate locks for faulthandler");
1096 return -1;
1097 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001098 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001099#endif
1100
1101 return faulthandler_env_options();
1102}
1103
1104void _PyFaulthandler_Fini(void)
1105{
1106#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001107 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001108#endif
1109
1110#ifdef FAULTHANDLER_LATER
1111 /* later */
Victor Stinnerde10f402011-04-08 12:57:06 +02001112 cancel_dump_tracebacks_later();
Victor Stinner024e37a2011-03-31 01:31:06 +02001113 if (thread.cancel_event) {
Victor Stinnerde10f402011-04-08 12:57:06 +02001114 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001115 PyThread_free_lock(thread.cancel_event);
1116 thread.cancel_event = NULL;
1117 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001118 if (thread.running) {
1119 PyThread_free_lock(thread.running);
1120 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001121 }
1122#endif
1123
1124#ifdef FAULTHANDLER_USER
1125 /* user */
1126 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001127 for (signum=0; signum < NSIG; signum++)
1128 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001129 free(user_signals);
1130 user_signals = NULL;
1131 }
1132#endif
1133
1134 /* fatal */
1135 faulthandler_disable();
1136#ifdef HAVE_SIGALTSTACK
1137 if (stack.ss_sp != NULL) {
1138 PyMem_Free(stack.ss_sp);
1139 stack.ss_sp = NULL;
1140 }
1141#endif
1142}