blob: b0df93c8a1c9229c579266778e0ebaba5bac91d0 [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 */
Victor Stinner024e37a2011-03-31 01:31:06 +020082#ifndef NSIG
83# if defined(_NSIG)
84# define NSIG _NSIG /* For BSD/SysV */
85# elif defined(_SIGMAX)
86# define NSIG (_SIGMAX + 1) /* For QNX */
87# elif defined(SIGMAX)
88# define NSIG (SIGMAX + 1) /* For djgpp */
89# else
90# define NSIG 64 /* Use a reasonable default value */
91# endif
92#endif
93
Victor Stinnera9a9dab2011-07-13 23:39:53 +020094static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +020095#endif /* FAULTHANDLER_USER */
96
97
98static fault_handler_t faulthandler_handlers[] = {
99#ifdef SIGBUS
100 {SIGBUS, 0, "Bus error", },
101#endif
102#ifdef SIGILL
103 {SIGILL, 0, "Illegal instruction", },
104#endif
105 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200106 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200107 /* define SIGSEGV at the end to make it the default choice if searching the
108 handler fails in faulthandler_fatal_error() */
109 {SIGSEGV, 0, "Segmentation fault", }
110};
111static const unsigned char faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200112 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200113
114#ifdef HAVE_SIGALTSTACK
115static stack_t stack;
116#endif
117
118
119/* Get the file descriptor of a file by calling its fileno() method and then
120 call its flush() method.
121
122 If file is NULL or Py_None, use sys.stderr as the new file.
123
124 On success, return the new file and write the file descriptor into *p_fd.
125 On error, return NULL. */
126
127static PyObject*
128faulthandler_get_fileno(PyObject *file, int *p_fd)
129{
130 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200131 _Py_IDENTIFIER(fileno);
132 _Py_IDENTIFIER(flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200133 long fd_long;
134 int fd;
135
136 if (file == NULL || file == Py_None) {
137 file = PySys_GetObject("stderr");
138 if (file == NULL) {
139 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
140 return NULL;
141 }
142 }
143
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200144 result = _PyObject_CallMethodId(file, &PyId_fileno, "");
Victor Stinner024e37a2011-03-31 01:31:06 +0200145 if (result == NULL)
146 return NULL;
147
148 fd = -1;
149 if (PyLong_Check(result)) {
150 fd_long = PyLong_AsLong(result);
151 if (0 <= fd_long && fd_long < INT_MAX)
152 fd = (int)fd_long;
153 }
154 Py_DECREF(result);
155
156 if (fd == -1) {
157 PyErr_SetString(PyExc_RuntimeError,
158 "file.fileno() is not a valid file descriptor");
159 return NULL;
160 }
161
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200162 result = _PyObject_CallMethodId(file, &PyId_flush, "");
Victor Stinner024e37a2011-03-31 01:31:06 +0200163 if (result != NULL)
164 Py_DECREF(result);
165 else {
166 /* ignore flush() error */
167 PyErr_Clear();
168 }
169 *p_fd = fd;
170 return file;
171}
172
Victor Stinnera4de6d82011-04-09 00:47:23 +0200173/* Get the state of the current thread: only call this function if the current
174 thread holds the GIL. Raise an exception on error. */
175static PyThreadState*
176get_thread_state(void)
177{
178 PyThreadState *tstate = PyThreadState_Get();
179 if (tstate == NULL) {
180 PyErr_SetString(PyExc_RuntimeError,
181 "unable to get the current thread state");
182 return NULL;
183 }
184 return tstate;
185}
186
Victor Stinner024e37a2011-03-31 01:31:06 +0200187static PyObject*
188faulthandler_dump_traceback_py(PyObject *self,
189 PyObject *args, PyObject *kwargs)
190{
191 static char *kwlist[] = {"file", "all_threads", NULL};
192 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200193 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200194 PyThreadState *tstate;
195 const char *errmsg;
196 int fd;
197
198 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
199 "|Oi:dump_traceback", kwlist,
200 &file, &all_threads))
201 return NULL;
202
203 file = faulthandler_get_fileno(file, &fd);
204 if (file == NULL)
205 return NULL;
206
Victor Stinnera4de6d82011-04-09 00:47:23 +0200207 tstate = get_thread_state();
208 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200209 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200210
211 if (all_threads) {
212 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
213 if (errmsg != NULL) {
214 PyErr_SetString(PyExc_RuntimeError, errmsg);
215 return NULL;
216 }
217 }
218 else {
219 _Py_DumpTraceback(fd, tstate);
220 }
221 Py_RETURN_NONE;
222}
223
224
Victor Stinner410dd7d2011-05-11 20:56:08 +0200225/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200226
227 Display the current Python traceback, restore the previous handler and call
228 the previous handler.
229
Victor Stinner410dd7d2011-05-11 20:56:08 +0200230 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200231 signal handler would not be called (for an unknown reason). The execution of
232 the program continues at faulthandler_fatal_error() exit, but the same
233 instruction will raise the same fault (signal), and so the previous handler
234 will be called.
235
Victor Stinner410dd7d2011-05-11 20:56:08 +0200236 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200237
238static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200239faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200240{
241 const int fd = fatal_error.fd;
242 unsigned int i;
243 fault_handler_t *handler = NULL;
244 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200245 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200246
247 if (!fatal_error.enabled)
248 return;
249
250 for (i=0; i < faulthandler_nsignals; i++) {
251 handler = &faulthandler_handlers[i];
252 if (handler->signum == signum)
253 break;
254 }
255 if (handler == NULL) {
256 /* faulthandler_nsignals == 0 (unlikely) */
257 return;
258 }
259
260 /* restore the previous handler */
261#ifdef HAVE_SIGACTION
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200262 (void)sigaction(signum, &handler->previous, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200263#else
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200264 (void)signal(signum, handler->previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200265#endif
266 handler->enabled = 0;
267
268 PUTS(fd, "Fatal Python error: ");
269 PUTS(fd, handler->name);
270 PUTS(fd, "\n\n");
271
Victor Stinnerff4cd882011-04-07 11:50:25 +0200272#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200273 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
Victor Stinner410dd7d2011-05-11 20:56:08 +0200274 are thus delivered to the thread that caused the fault. Get the Python
Victor Stinnerd727e232011-04-01 12:13:55 +0200275 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200276
277 PyThreadState_Get() doesn't give the state of the thread that caused the
278 fault if the thread released the GIL, and so this function cannot be
279 used. Read the thread local storage (TLS) instead: call
280 PyGILState_GetThisThreadState(). */
281 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200282#else
283 tstate = PyThreadState_Get();
284#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200285
286 if (fatal_error.all_threads)
Victor Stinnera4de6d82011-04-09 00:47:23 +0200287 _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate);
288 else {
289 if (tstate != NULL)
290 _Py_DumpTraceback(fd, tstate);
291 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200292
Victor Stinnerc9256172011-05-07 12:20:11 +0200293 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200294#ifdef MS_WINDOWS
295 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200296 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200297 handler, because the Windows signal handler would not be called */
298 return;
299 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200300#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200301 /* call the previous signal handler: it is called immediatly if we use
302 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
303 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200304}
305
Victor Stinnerd727e232011-04-01 12:13:55 +0200306/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200307
308static PyObject*
309faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
310{
311 static char *kwlist[] = {"file", "all_threads", NULL};
312 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200313 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200314 unsigned int i;
315 fault_handler_t *handler;
316#ifdef HAVE_SIGACTION
317 struct sigaction action;
318#endif
319 int err;
320 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200321 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200322
323 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
324 "|Oi:enable", kwlist, &file, &all_threads))
325 return NULL;
326
327 file = faulthandler_get_fileno(file, &fd);
328 if (file == NULL)
329 return NULL;
330
Victor Stinnera4de6d82011-04-09 00:47:23 +0200331 tstate = get_thread_state();
332 if (tstate == NULL)
333 return NULL;
334
Victor Stinner024e37a2011-03-31 01:31:06 +0200335 Py_XDECREF(fatal_error.file);
336 Py_INCREF(file);
337 fatal_error.file = file;
338 fatal_error.fd = fd;
339 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200340 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200341
342 if (!fatal_error.enabled) {
343 fatal_error.enabled = 1;
344
345 for (i=0; i < faulthandler_nsignals; i++) {
346 handler = &faulthandler_handlers[i];
347#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200348 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200349 sigemptyset(&action.sa_mask);
350 /* Do not prevent the signal from being received from within
351 its own signal handler */
352 action.sa_flags = SA_NODEFER;
353#ifdef HAVE_SIGALTSTACK
354 if (stack.ss_sp != NULL) {
355 /* Call the signal handler on an alternate signal stack
356 provided by sigaltstack() */
357 action.sa_flags |= SA_ONSTACK;
358 }
359#endif
360 err = sigaction(handler->signum, &action, &handler->previous);
361#else
362 handler->previous = signal(handler->signum,
363 faulthandler_fatal_error);
364 err = (handler->previous == SIG_ERR);
365#endif
366 if (err) {
367 PyErr_SetFromErrno(PyExc_RuntimeError);
368 return NULL;
369 }
370 handler->enabled = 1;
371 }
372 }
373 Py_RETURN_NONE;
374}
375
376static void
377faulthandler_disable(void)
378{
379 unsigned int i;
380 fault_handler_t *handler;
381
382 if (fatal_error.enabled) {
383 fatal_error.enabled = 0;
384 for (i=0; i < faulthandler_nsignals; i++) {
385 handler = &faulthandler_handlers[i];
386 if (!handler->enabled)
387 continue;
388#ifdef HAVE_SIGACTION
389 (void)sigaction(handler->signum, &handler->previous, NULL);
390#else
391 (void)signal(handler->signum, handler->previous);
392#endif
393 handler->enabled = 0;
394 }
395 }
396
397 Py_CLEAR(fatal_error.file);
398}
399
400static PyObject*
401faulthandler_disable_py(PyObject *self)
402{
403 if (!fatal_error.enabled) {
404 Py_INCREF(Py_False);
405 return Py_False;
406 }
407 faulthandler_disable();
408 Py_INCREF(Py_True);
409 return Py_True;
410}
411
412static PyObject*
413faulthandler_is_enabled(PyObject *self)
414{
415 return PyBool_FromLong(fatal_error.enabled);
416}
417
418#ifdef FAULTHANDLER_LATER
419
420static void
421faulthandler_thread(void *unused)
422{
423 PyLockStatus st;
424 const char* errmsg;
425 PyThreadState *current;
426 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200427#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200428 sigset_t set;
429
430 /* we don't want to receive any signal */
431 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200432 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200433#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200434
435 do {
436 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200437 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200438 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200439 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200440 break;
441 }
442 /* Timeout => dump traceback */
443 assert(st == PY_LOCK_FAILURE);
444
445 /* get the thread holding the GIL, NULL if no thread hold the GIL */
446 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
447
Victor Stinnerc790a532011-04-08 13:39:59 +0200448 write(thread.fd, thread.header, thread.header_len);
449
Victor Stinner024e37a2011-03-31 01:31:06 +0200450 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
451 ok = (errmsg == NULL);
452
453 if (thread.exit)
454 _exit(1);
455 } while (ok && thread.repeat);
456
457 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200458 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200459}
460
461static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200462cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200463{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200464 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200465 PyThread_release_lock(thread.cancel_event);
466
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200467 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200468 PyThread_acquire_lock(thread.running, 1);
469 PyThread_release_lock(thread.running);
470
471 /* The main thread should always hold the cancel_event lock */
472 PyThread_acquire_lock(thread.cancel_event, 1);
473
Victor Stinner024e37a2011-03-31 01:31:06 +0200474 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200475 if (thread.header) {
476 free(thread.header);
477 thread.header = NULL;
478 }
479}
480
481static char*
482format_timeout(double timeout)
483{
484 unsigned long us, sec, min, hour;
485 double intpart, fracpart;
486 char buffer[100];
487
488 fracpart = modf(timeout, &intpart);
489 sec = (unsigned long)intpart;
490 us = (unsigned long)(fracpart * 1e6);
491 min = sec / 60;
492 sec %= 60;
493 hour = min / 60;
494 min %= 60;
495
496 if (us != 0)
497 PyOS_snprintf(buffer, sizeof(buffer),
498 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
499 hour, min, sec, us);
500 else
501 PyOS_snprintf(buffer, sizeof(buffer),
502 "Timeout (%lu:%02lu:%02lu)!\n",
503 hour, min, sec);
504
505 return strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200506}
507
508static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200509faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200510 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200511{
512 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
513 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200514 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200515 int repeat = 0;
516 PyObject *file = NULL;
517 int fd;
518 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200519 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200520 char *header;
521 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200522
523 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Georg Brandldeb92b52012-09-22 08:58:55 +0200524 "d|iOi:dump_traceback_later", kwlist,
Victor Stinner024e37a2011-03-31 01:31:06 +0200525 &timeout, &repeat, &file, &exit))
526 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200527 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200528 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
529 return NULL;
530 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200531 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200532 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200533 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
534 return NULL;
535 }
536
Victor Stinnera4de6d82011-04-09 00:47:23 +0200537 tstate = get_thread_state();
538 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200539 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200540
Victor Stinner024e37a2011-03-31 01:31:06 +0200541 file = faulthandler_get_fileno(file, &fd);
542 if (file == NULL)
543 return NULL;
544
Victor Stinnerc790a532011-04-08 13:39:59 +0200545 /* format the timeout */
546 header = format_timeout(timeout);
547 if (header == NULL)
548 return PyErr_NoMemory();
549 header_len = strlen(header);
550
Victor Stinner024e37a2011-03-31 01:31:06 +0200551 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200552 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200553
554 Py_XDECREF(thread.file);
555 Py_INCREF(file);
556 thread.file = file;
557 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200558 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200559 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200560 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200561 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200562 thread.header = header;
563 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200564
565 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200566 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200567
Victor Stinner024e37a2011-03-31 01:31:06 +0200568 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200569 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200570 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200571 free(header);
572 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200573 PyErr_SetString(PyExc_RuntimeError,
574 "unable to start watchdog thread");
575 return NULL;
576 }
577
578 Py_RETURN_NONE;
579}
580
581static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200582faulthandler_cancel_dump_traceback_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200583{
Georg Brandldeb92b52012-09-22 08:58:55 +0200584 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200585 Py_RETURN_NONE;
586}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200587#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200588
589#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200590static int
591faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
592{
593#ifdef HAVE_SIGACTION
594 struct sigaction action;
595 action.sa_handler = faulthandler_user;
596 sigemptyset(&action.sa_mask);
597 /* if the signal is received while the kernel is executing a system
598 call, try to restart the system call instead of interrupting it and
599 return EINTR. */
600 action.sa_flags = SA_RESTART;
601 if (chain) {
602 /* do not prevent the signal from being received from within its
603 own signal handler */
604 action.sa_flags = SA_NODEFER;
605 }
606#ifdef HAVE_SIGALTSTACK
607 if (stack.ss_sp != NULL) {
608 /* Call the signal handler on an alternate signal stack
609 provided by sigaltstack() */
610 action.sa_flags |= SA_ONSTACK;
611 }
612#endif
613 return sigaction(signum, &action, p_previous);
614#else
615 _Py_sighandler_t previous;
616 previous = signal(signum, faulthandler_user);
617 if (p_previous != NULL)
618 *p_previous = previous;
619 return (previous == SIG_ERR);
620#endif
621}
622
Victor Stinner024e37a2011-03-31 01:31:06 +0200623/* Handler of user signals (e.g. SIGUSR1).
624
625 Dump the traceback of the current thread, or of all threads if
626 thread.all_threads is true.
627
628 This function is signal safe and should only call signal safe functions. */
629
630static void
631faulthandler_user(int signum)
632{
633 user_signal_t *user;
634 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200635 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200636
637 user = &user_signals[signum];
638 if (!user->enabled)
639 return;
640
Victor Stinnerff4cd882011-04-07 11:50:25 +0200641#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200642 /* PyThreadState_Get() doesn't give the state of the current thread if
643 the thread doesn't hold the GIL. Read the thread local storage (TLS)
644 instead: call PyGILState_GetThisThreadState(). */
645 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200646#else
647 tstate = PyThreadState_Get();
648#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200649
650 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200651 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
652 else {
Victor Stinner98a387b2012-08-01 19:36:36 +0200653 if (tstate != NULL)
654 _Py_DumpTraceback(user->fd, tstate);
Victor Stinner44378d42011-04-01 15:37:12 +0200655 }
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200656#ifdef HAVE_SIGACTION
657 if (user->chain) {
658 (void)sigaction(signum, &user->previous, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200659 errno = save_errno;
660
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200661 /* call the previous signal handler */
662 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200663
664 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200665 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200666 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200667 }
668#else
669 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200670 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200671 /* call the previous signal handler */
672 user->previous(signum);
673 }
674#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200675}
676
677static int
678check_signum(int signum)
679{
680 unsigned int i;
681
682 for (i=0; i < faulthandler_nsignals; i++) {
683 if (faulthandler_handlers[i].signum == signum) {
684 PyErr_Format(PyExc_RuntimeError,
685 "signal %i cannot be registered, "
686 "use enable() instead",
687 signum);
688 return 0;
689 }
690 }
691 if (signum < 1 || NSIG <= signum) {
692 PyErr_SetString(PyExc_ValueError, "signal number out of range");
693 return 0;
694 }
695 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200696}
697
698static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200699faulthandler_register_py(PyObject *self,
700 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200701{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200702 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200703 int signum;
704 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200705 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200706 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200707 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200708 user_signal_t *user;
709 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200710 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200711 int err;
712
713 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200714 "i|Oii:register", kwlist,
715 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200716 return NULL;
717
Victor Stinner44378d42011-04-01 15:37:12 +0200718 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200719 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200720
Victor Stinnera4de6d82011-04-09 00:47:23 +0200721 tstate = get_thread_state();
722 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200723 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200724
725 file = faulthandler_get_fileno(file, &fd);
726 if (file == NULL)
727 return NULL;
728
729 if (user_signals == NULL) {
730 user_signals = calloc(NSIG, sizeof(user_signal_t));
731 if (user_signals == NULL)
732 return PyErr_NoMemory();
733 }
734 user = &user_signals[signum];
735
736 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200737 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200738 if (err) {
739 PyErr_SetFromErrno(PyExc_OSError);
740 return NULL;
741 }
742 }
743
744 Py_XDECREF(user->file);
745 Py_INCREF(file);
746 user->file = file;
747 user->fd = fd;
748 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200749 user->chain = chain;
Victor Stinner024e37a2011-03-31 01:31:06 +0200750 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200751 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200752 user->enabled = 1;
753
754 Py_RETURN_NONE;
755}
756
757static int
758faulthandler_unregister(user_signal_t *user, int signum)
759{
Victor Stinnera01ca122011-04-01 12:56:17 +0200760 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200761 return 0;
762 user->enabled = 0;
763#ifdef HAVE_SIGACTION
764 (void)sigaction(signum, &user->previous, NULL);
765#else
766 (void)signal(signum, user->previous);
767#endif
768 Py_CLEAR(user->file);
769 user->fd = -1;
770 return 1;
771}
772
773static PyObject*
774faulthandler_unregister_py(PyObject *self, PyObject *args)
775{
776 int signum;
777 user_signal_t *user;
778 int change;
779
780 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
781 return NULL;
782
Victor Stinner44378d42011-04-01 15:37:12 +0200783 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200784 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200785
Victor Stinnercfa71232011-04-08 12:48:15 +0200786 if (user_signals == NULL)
787 Py_RETURN_FALSE;
788
Victor Stinner024e37a2011-03-31 01:31:06 +0200789 user = &user_signals[signum];
790 change = faulthandler_unregister(user, signum);
791 return PyBool_FromLong(change);
792}
793#endif /* FAULTHANDLER_USER */
794
795
796static PyObject *
797faulthandler_read_null(PyObject *self, PyObject *args)
798{
Victor Stinnera2477202012-01-30 00:07:43 +0100799 volatile int *x;
800 volatile int y;
Victor Stinner024e37a2011-03-31 01:31:06 +0200801 int release_gil = 0;
802 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
803 return NULL;
Victor Stinnera2477202012-01-30 00:07:43 +0100804
805 x = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200806 if (release_gil) {
807 Py_BEGIN_ALLOW_THREADS
808 y = *x;
809 Py_END_ALLOW_THREADS
810 } else
811 y = *x;
812 return PyLong_FromLong(y);
813
814}
815
816static PyObject *
817faulthandler_sigsegv(PyObject *self, PyObject *args)
818{
819#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200820 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
821 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200822 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200823 SIGSEGV was raised by the kernel because of a fault, and so if the
824 program retries to execute the same instruction, the fault will be
825 raised again.
826
827 Here the fault is simulated by a fake SIGSEGV signal raised by the
828 application. We have to raise SIGSEGV at lease twice: once for
829 faulthandler_fatal_error(), and one more time for the previous signal
830 handler. */
831 while(1)
832 raise(SIGSEGV);
833#else
834 raise(SIGSEGV);
835#endif
836 Py_RETURN_NONE;
837}
838
839static PyObject *
840faulthandler_sigfpe(PyObject *self, PyObject *args)
841{
842 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
843 PowerPC. Use volatile to disable compile-time optimizations. */
844 volatile int x = 1, y = 0, z;
845 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +0200846 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
847 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200848 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +0200849 /* This line is never reached, but we pretend to make something with z
850 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +0200851 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +0200852}
853
Victor Stinnerd727e232011-04-01 12:13:55 +0200854static PyObject *
855faulthandler_sigabrt(PyObject *self, PyObject *args)
856{
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200857#ifdef _MSC_VER
858 /* Visual Studio: configure abort() to not display an error message nor
859 open a popup asking to report the fault. */
860 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
Victor Stinnerd727e232011-04-01 12:13:55 +0200861#endif
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200862 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +0200863 Py_RETURN_NONE;
864}
865
Victor Stinner024e37a2011-03-31 01:31:06 +0200866#ifdef SIGBUS
867static PyObject *
868faulthandler_sigbus(PyObject *self, PyObject *args)
869{
870 raise(SIGBUS);
871 Py_RETURN_NONE;
872}
873#endif
874
875#ifdef SIGILL
876static PyObject *
877faulthandler_sigill(PyObject *self, PyObject *args)
878{
Victor Stinner024e37a2011-03-31 01:31:06 +0200879 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200880 Py_RETURN_NONE;
881}
882#endif
883
884static PyObject *
885faulthandler_fatal_error_py(PyObject *self, PyObject *args)
886{
887 char *message;
888 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
889 return NULL;
890 Py_FatalError(message);
891 Py_RETURN_NONE;
892}
893
894#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner9b493042011-05-23 12:29:10 +0200895static void*
Victor Stinnerf0480752011-03-31 11:34:08 +0200896stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200897{
898 /* allocate 4096 bytes on the stack at each call */
899 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200900 void *sp = &buffer;
901 *depth += 1;
902 if (sp < min_sp || max_sp < sp)
903 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200904 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200905 buffer[4095] = 0;
906 return stack_overflow(min_sp, max_sp, depth);
907}
908
909static PyObject *
910faulthandler_stack_overflow(PyObject *self)
911{
912 size_t depth, size;
Victor Stinner425fcd32011-09-07 16:18:56 +0200913 char *sp = (char *)&depth, *stop;
Victor Stinnerf0480752011-03-31 11:34:08 +0200914
915 depth = 0;
916 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
917 sp + STACK_OVERFLOW_MAX_SIZE,
918 &depth);
919 if (sp < stop)
920 size = stop - sp;
921 else
922 size = sp - stop;
923 PyErr_Format(PyExc_RuntimeError,
924 "unable to raise a stack overflow (allocated %zu bytes "
925 "on the stack, %zu recursive calls)",
926 size, depth);
927 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200928}
929#endif
930
931
932static int
933faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
934{
935#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200936 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200937#endif
938
939#ifdef FAULTHANDLER_LATER
940 Py_VISIT(thread.file);
941#endif
942#ifdef FAULTHANDLER_USER
943 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200944 for (signum=0; signum < NSIG; signum++)
945 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200946 }
947#endif
948 Py_VISIT(fatal_error.file);
949 return 0;
950}
951
952PyDoc_STRVAR(module_doc,
953"faulthandler module.");
954
955static PyMethodDef module_methods[] = {
956 {"enable",
957 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +0200958 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200959 "enable the fault handler")},
960 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
961 PyDoc_STR("disable(): disable the fault handler")},
962 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
963 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
964 {"dump_traceback",
965 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +0200966 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200967 "dump the traceback of the current thread, or of all threads "
968 "if all_threads is True, into file")},
969#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +0200970 {"dump_traceback_later",
971 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
972 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200973 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200974 "or each timeout seconds if repeat is True. If exit is True, "
975 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +0200976 {"cancel_dump_traceback_later",
977 (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
978 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
979 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200980#endif
981
982#ifdef FAULTHANDLER_USER
983 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200984 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
985 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200986 "register an handler for the signal 'signum': dump the "
987 "traceback of the current thread, or of all threads if "
988 "all_threads is True, into file")},
989 {"unregister",
990 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
991 PyDoc_STR("unregister(signum): unregister the handler of the signal "
992 "'signum' registered by register()")},
993#endif
994
995 {"_read_null", faulthandler_read_null, METH_VARARGS,
996 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
997 "a SIGSEGV or SIGBUS signal depending on the platform")},
998 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
999 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +02001000 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
1001 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001002 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1003 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
1004#ifdef SIGBUS
1005 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
1006 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
1007#endif
1008#ifdef SIGILL
1009 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
1010 PyDoc_STR("_sigill(): raise a SIGILL signal")},
1011#endif
1012 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1013 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
1014#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1015 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1016 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1017#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001018 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001019};
1020
1021static struct PyModuleDef module_def = {
1022 PyModuleDef_HEAD_INIT,
1023 "faulthandler",
1024 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001025 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001026 module_methods,
1027 NULL,
1028 faulthandler_traverse,
1029 NULL,
1030 NULL
1031};
1032
1033PyMODINIT_FUNC
1034PyInit_faulthandler(void)
1035{
1036 return PyModule_Create(&module_def);
1037}
1038
Victor Stinner410dd7d2011-05-11 20:56:08 +02001039/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1040 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001041
1042static int
1043faulthandler_env_options(void)
1044{
1045 PyObject *xoptions, *key, *module, *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001046 _Py_IDENTIFIER(enable);
Victor Stinner024e37a2011-03-31 01:31:06 +02001047
1048 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
Victor Stinner25095b22011-05-26 13:47:08 +02001049 int has_key;
1050
Victor Stinner024e37a2011-03-31 01:31:06 +02001051 xoptions = PySys_GetXOptions();
1052 if (xoptions == NULL)
1053 return -1;
1054
1055 key = PyUnicode_FromString("faulthandler");
1056 if (key == NULL)
1057 return -1;
1058
Victor Stinner25095b22011-05-26 13:47:08 +02001059 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001060 Py_DECREF(key);
Victor Stinner25095b22011-05-26 13:47:08 +02001061 if (!has_key)
Victor Stinner024e37a2011-03-31 01:31:06 +02001062 return 0;
1063 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001064
1065 module = PyImport_ImportModule("faulthandler");
1066 if (module == NULL) {
1067 return -1;
1068 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001069 res = _PyObject_CallMethodId(module, &PyId_enable, "");
Victor Stinner024e37a2011-03-31 01:31:06 +02001070 Py_DECREF(module);
1071 if (res == NULL)
1072 return -1;
1073 Py_DECREF(res);
1074 return 0;
1075}
1076
1077int _PyFaulthandler_Init(void)
1078{
1079#ifdef HAVE_SIGALTSTACK
1080 int err;
1081
1082 /* Try to allocate an alternate stack for faulthandler() signal handler to
1083 * be able to allocate memory on the stack, even on a stack overflow. If it
1084 * fails, ignore the error. */
1085 stack.ss_flags = 0;
1086 stack.ss_size = SIGSTKSZ;
1087 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1088 if (stack.ss_sp != NULL) {
1089 err = sigaltstack(&stack, NULL);
1090 if (err) {
1091 PyMem_Free(stack.ss_sp);
1092 stack.ss_sp = NULL;
1093 }
1094 }
1095#endif
1096#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001097 thread.file = NULL;
1098 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001099 thread.running = PyThread_allocate_lock();
1100 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001101 PyErr_SetString(PyExc_RuntimeError,
1102 "could not allocate locks for faulthandler");
1103 return -1;
1104 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001105 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001106#endif
1107
1108 return faulthandler_env_options();
1109}
1110
1111void _PyFaulthandler_Fini(void)
1112{
1113#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001114 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001115#endif
1116
1117#ifdef FAULTHANDLER_LATER
1118 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001119 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001120 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001121 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001122 PyThread_free_lock(thread.cancel_event);
1123 thread.cancel_event = NULL;
1124 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001125 if (thread.running) {
1126 PyThread_free_lock(thread.running);
1127 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001128 }
1129#endif
1130
1131#ifdef FAULTHANDLER_USER
1132 /* user */
1133 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001134 for (signum=0; signum < NSIG; signum++)
1135 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001136 free(user_signals);
1137 user_signals = NULL;
1138 }
1139#endif
1140
1141 /* fatal */
1142 faulthandler_disable();
1143#ifdef HAVE_SIGALTSTACK
1144 if (stack.ss_sp != NULL) {
1145 PyMem_Free(stack.ss_sp);
1146 stack.ss_sp = NULL;
1147 }
1148#endif
1149}