blob: f49993d0f3974d2666d7d6bcdbbe833632a61cf7 [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
Victor Stinner56cb1252012-10-31 00:33:57 +010025/* cast size_t to int because write() takes an int on Windows
26 (anyway, the length is smaller than 30 characters) */
27#define PUTS(fd, str) write(fd, str, (int)strlen(str))
Victor Stinner024e37a2011-03-31 01:31:06 +020028
29#ifdef HAVE_SIGACTION
30typedef struct sigaction _Py_sighandler_t;
31#else
32typedef PyOS_sighandler_t _Py_sighandler_t;
33#endif
34
35typedef struct {
36 int signum;
37 int enabled;
38 const char* name;
39 _Py_sighandler_t previous;
40 int all_threads;
41} fault_handler_t;
42
43static struct {
44 int enabled;
45 PyObject *file;
46 int fd;
47 int all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +020048 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020049} fatal_error = {0, NULL, -1, 0};
50
51#ifdef FAULTHANDLER_LATER
52static struct {
53 PyObject *file;
54 int fd;
Victor Stinner94189322011-04-08 13:00:31 +020055 PY_TIMEOUT_T timeout_us; /* timeout in microseconds */
Victor Stinner024e37a2011-03-31 01:31:06 +020056 int repeat;
Victor Stinner024e37a2011-03-31 01:31:06 +020057 PyInterpreterState *interp;
58 int exit;
Victor Stinnerc790a532011-04-08 13:39:59 +020059 char *header;
60 size_t header_len;
Victor Stinner410dd7d2011-05-11 20:56:08 +020061 /* The main thread always holds this lock. It is only released when
62 faulthandler_thread() is interrupted before this thread exits, or at
Victor Stinnerde10f402011-04-08 12:57:06 +020063 Python exit. */
Victor Stinner024e37a2011-03-31 01:31:06 +020064 PyThread_type_lock cancel_event;
65 /* released by child thread when joined */
Victor Stinnerde10f402011-04-08 12:57:06 +020066 PyThread_type_lock running;
Victor Stinner024e37a2011-03-31 01:31:06 +020067} thread;
68#endif
69
70#ifdef FAULTHANDLER_USER
71typedef struct {
72 int enabled;
73 PyObject *file;
74 int fd;
75 int all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +020076 int chain;
Victor Stinner024e37a2011-03-31 01:31:06 +020077 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +020078 PyInterpreterState *interp;
Victor Stinner024e37a2011-03-31 01:31:06 +020079} user_signal_t;
80
81static user_signal_t *user_signals;
82
83/* the following macros come from Python: Modules/signalmodule.c */
Victor Stinner024e37a2011-03-31 01:31:06 +020084#ifndef NSIG
85# if defined(_NSIG)
86# define NSIG _NSIG /* For BSD/SysV */
87# elif defined(_SIGMAX)
88# define NSIG (_SIGMAX + 1) /* For QNX */
89# elif defined(SIGMAX)
90# define NSIG (SIGMAX + 1) /* For djgpp */
91# else
92# define NSIG 64 /* Use a reasonable default value */
93# endif
94#endif
95
Victor Stinnera9a9dab2011-07-13 23:39:53 +020096static void faulthandler_user(int signum);
Victor Stinner024e37a2011-03-31 01:31:06 +020097#endif /* FAULTHANDLER_USER */
98
99
100static fault_handler_t faulthandler_handlers[] = {
101#ifdef SIGBUS
102 {SIGBUS, 0, "Bus error", },
103#endif
104#ifdef SIGILL
105 {SIGILL, 0, "Illegal instruction", },
106#endif
107 {SIGFPE, 0, "Floating point exception", },
Victor Stinnerd727e232011-04-01 12:13:55 +0200108 {SIGABRT, 0, "Aborted", },
Victor Stinner024e37a2011-03-31 01:31:06 +0200109 /* define SIGSEGV at the end to make it the default choice if searching the
110 handler fails in faulthandler_fatal_error() */
111 {SIGSEGV, 0, "Segmentation fault", }
112};
113static const unsigned char faulthandler_nsignals = \
Victor Stinner63941882011-09-29 00:42:28 +0200114 Py_ARRAY_LENGTH(faulthandler_handlers);
Victor Stinner024e37a2011-03-31 01:31:06 +0200115
116#ifdef HAVE_SIGALTSTACK
117static stack_t stack;
118#endif
119
120
121/* Get the file descriptor of a file by calling its fileno() method and then
122 call its flush() method.
123
124 If file is NULL or Py_None, use sys.stderr as the new file.
125
126 On success, return the new file and write the file descriptor into *p_fd.
127 On error, return NULL. */
128
129static PyObject*
130faulthandler_get_fileno(PyObject *file, int *p_fd)
131{
132 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200133 _Py_IDENTIFIER(fileno);
134 _Py_IDENTIFIER(flush);
Victor Stinner024e37a2011-03-31 01:31:06 +0200135 long fd_long;
136 int fd;
137
138 if (file == NULL || file == Py_None) {
139 file = PySys_GetObject("stderr");
140 if (file == NULL) {
141 PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
142 return NULL;
143 }
144 }
145
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200146 result = _PyObject_CallMethodId(file, &PyId_fileno, "");
Victor Stinner024e37a2011-03-31 01:31:06 +0200147 if (result == NULL)
148 return NULL;
149
150 fd = -1;
151 if (PyLong_Check(result)) {
152 fd_long = PyLong_AsLong(result);
153 if (0 <= fd_long && fd_long < INT_MAX)
154 fd = (int)fd_long;
155 }
156 Py_DECREF(result);
157
158 if (fd == -1) {
159 PyErr_SetString(PyExc_RuntimeError,
160 "file.fileno() is not a valid file descriptor");
161 return NULL;
162 }
163
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200164 result = _PyObject_CallMethodId(file, &PyId_flush, "");
Victor Stinner024e37a2011-03-31 01:31:06 +0200165 if (result != NULL)
166 Py_DECREF(result);
167 else {
168 /* ignore flush() error */
169 PyErr_Clear();
170 }
171 *p_fd = fd;
172 return file;
173}
174
Victor Stinnera4de6d82011-04-09 00:47:23 +0200175/* Get the state of the current thread: only call this function if the current
176 thread holds the GIL. Raise an exception on error. */
177static PyThreadState*
178get_thread_state(void)
179{
180 PyThreadState *tstate = PyThreadState_Get();
181 if (tstate == NULL) {
182 PyErr_SetString(PyExc_RuntimeError,
183 "unable to get the current thread state");
184 return NULL;
185 }
186 return tstate;
187}
188
Victor Stinner024e37a2011-03-31 01:31:06 +0200189static PyObject*
190faulthandler_dump_traceback_py(PyObject *self,
191 PyObject *args, PyObject *kwargs)
192{
193 static char *kwlist[] = {"file", "all_threads", NULL};
194 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200195 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200196 PyThreadState *tstate;
197 const char *errmsg;
198 int fd;
199
200 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
201 "|Oi:dump_traceback", kwlist,
202 &file, &all_threads))
203 return NULL;
204
205 file = faulthandler_get_fileno(file, &fd);
206 if (file == NULL)
207 return NULL;
208
Victor Stinnera4de6d82011-04-09 00:47:23 +0200209 tstate = get_thread_state();
210 if (tstate == NULL)
Victor Stinner024e37a2011-03-31 01:31:06 +0200211 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200212
213 if (all_threads) {
214 errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
215 if (errmsg != NULL) {
216 PyErr_SetString(PyExc_RuntimeError, errmsg);
217 return NULL;
218 }
219 }
220 else {
221 _Py_DumpTraceback(fd, tstate);
222 }
223 Py_RETURN_NONE;
224}
225
226
Victor Stinner410dd7d2011-05-11 20:56:08 +0200227/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
Victor Stinner024e37a2011-03-31 01:31:06 +0200228
229 Display the current Python traceback, restore the previous handler and call
230 the previous handler.
231
Victor Stinner410dd7d2011-05-11 20:56:08 +0200232 On Windows, don't explicitly call the previous handler, because the Windows
Victor Stinner024e37a2011-03-31 01:31:06 +0200233 signal handler would not be called (for an unknown reason). The execution of
234 the program continues at faulthandler_fatal_error() exit, but the same
235 instruction will raise the same fault (signal), and so the previous handler
236 will be called.
237
Victor Stinner410dd7d2011-05-11 20:56:08 +0200238 This function is signal-safe and should only call signal-safe functions. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200239
240static void
Victor Stinner44e31ba2011-04-07 11:39:03 +0200241faulthandler_fatal_error(int signum)
Victor Stinner024e37a2011-03-31 01:31:06 +0200242{
243 const int fd = fatal_error.fd;
244 unsigned int i;
245 fault_handler_t *handler = NULL;
246 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200247 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200248
249 if (!fatal_error.enabled)
250 return;
251
252 for (i=0; i < faulthandler_nsignals; i++) {
253 handler = &faulthandler_handlers[i];
254 if (handler->signum == signum)
255 break;
256 }
257 if (handler == NULL) {
258 /* faulthandler_nsignals == 0 (unlikely) */
259 return;
260 }
261
262 /* restore the previous handler */
263#ifdef HAVE_SIGACTION
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200264 (void)sigaction(signum, &handler->previous, NULL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200265#else
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200266 (void)signal(signum, handler->previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200267#endif
268 handler->enabled = 0;
269
270 PUTS(fd, "Fatal Python error: ");
271 PUTS(fd, handler->name);
272 PUTS(fd, "\n\n");
273
Victor Stinnerff4cd882011-04-07 11:50:25 +0200274#ifdef WITH_THREAD
Victor Stinnerd727e232011-04-01 12:13:55 +0200275 /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
Victor Stinner410dd7d2011-05-11 20:56:08 +0200276 are thus delivered to the thread that caused the fault. Get the Python
Victor Stinnerd727e232011-04-01 12:13:55 +0200277 thread state of the current thread.
Victor Stinner024e37a2011-03-31 01:31:06 +0200278
279 PyThreadState_Get() doesn't give the state of the thread that caused the
280 fault if the thread released the GIL, and so this function cannot be
281 used. Read the thread local storage (TLS) instead: call
282 PyGILState_GetThisThreadState(). */
283 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200284#else
285 tstate = PyThreadState_Get();
286#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200287
288 if (fatal_error.all_threads)
Victor Stinnera4de6d82011-04-09 00:47:23 +0200289 _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate);
290 else {
291 if (tstate != NULL)
292 _Py_DumpTraceback(fd, tstate);
293 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200294
Victor Stinnerc9256172011-05-07 12:20:11 +0200295 errno = save_errno;
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200296#ifdef MS_WINDOWS
297 if (signum == SIGSEGV) {
Victor Stinner410dd7d2011-05-11 20:56:08 +0200298 /* don't explicitly call the previous handler for SIGSEGV in this signal
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200299 handler, because the Windows signal handler would not be called */
300 return;
301 }
Victor Stinner024e37a2011-03-31 01:31:06 +0200302#endif
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200303 /* call the previous signal handler: it is called immediatly if we use
304 sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */
305 raise(signum);
Victor Stinner024e37a2011-03-31 01:31:06 +0200306}
307
Victor Stinnerd727e232011-04-01 12:13:55 +0200308/* Install the handler for fatal signals, faulthandler_fatal_error(). */
Victor Stinner024e37a2011-03-31 01:31:06 +0200309
310static PyObject*
311faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
312{
313 static char *kwlist[] = {"file", "all_threads", NULL};
314 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200315 int all_threads = 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200316 unsigned int i;
317 fault_handler_t *handler;
318#ifdef HAVE_SIGACTION
319 struct sigaction action;
320#endif
321 int err;
322 int fd;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200323 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200324
325 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
326 "|Oi:enable", kwlist, &file, &all_threads))
327 return NULL;
328
329 file = faulthandler_get_fileno(file, &fd);
330 if (file == NULL)
331 return NULL;
332
Victor Stinnera4de6d82011-04-09 00:47:23 +0200333 tstate = get_thread_state();
334 if (tstate == NULL)
335 return NULL;
336
Victor Stinner024e37a2011-03-31 01:31:06 +0200337 Py_XDECREF(fatal_error.file);
338 Py_INCREF(file);
339 fatal_error.file = file;
340 fatal_error.fd = fd;
341 fatal_error.all_threads = all_threads;
Victor Stinnera4de6d82011-04-09 00:47:23 +0200342 fatal_error.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200343
344 if (!fatal_error.enabled) {
345 fatal_error.enabled = 1;
346
347 for (i=0; i < faulthandler_nsignals; i++) {
348 handler = &faulthandler_handlers[i];
349#ifdef HAVE_SIGACTION
Victor Stinner44e31ba2011-04-07 11:39:03 +0200350 action.sa_handler = faulthandler_fatal_error;
Victor Stinner024e37a2011-03-31 01:31:06 +0200351 sigemptyset(&action.sa_mask);
352 /* Do not prevent the signal from being received from within
353 its own signal handler */
354 action.sa_flags = SA_NODEFER;
355#ifdef HAVE_SIGALTSTACK
356 if (stack.ss_sp != NULL) {
357 /* Call the signal handler on an alternate signal stack
358 provided by sigaltstack() */
359 action.sa_flags |= SA_ONSTACK;
360 }
361#endif
362 err = sigaction(handler->signum, &action, &handler->previous);
363#else
364 handler->previous = signal(handler->signum,
365 faulthandler_fatal_error);
366 err = (handler->previous == SIG_ERR);
367#endif
368 if (err) {
369 PyErr_SetFromErrno(PyExc_RuntimeError);
370 return NULL;
371 }
372 handler->enabled = 1;
373 }
374 }
375 Py_RETURN_NONE;
376}
377
378static void
379faulthandler_disable(void)
380{
381 unsigned int i;
382 fault_handler_t *handler;
383
384 if (fatal_error.enabled) {
385 fatal_error.enabled = 0;
386 for (i=0; i < faulthandler_nsignals; i++) {
387 handler = &faulthandler_handlers[i];
388 if (!handler->enabled)
389 continue;
390#ifdef HAVE_SIGACTION
391 (void)sigaction(handler->signum, &handler->previous, NULL);
392#else
393 (void)signal(handler->signum, handler->previous);
394#endif
395 handler->enabled = 0;
396 }
397 }
398
399 Py_CLEAR(fatal_error.file);
400}
401
402static PyObject*
403faulthandler_disable_py(PyObject *self)
404{
405 if (!fatal_error.enabled) {
406 Py_INCREF(Py_False);
407 return Py_False;
408 }
409 faulthandler_disable();
410 Py_INCREF(Py_True);
411 return Py_True;
412}
413
414static PyObject*
415faulthandler_is_enabled(PyObject *self)
416{
417 return PyBool_FromLong(fatal_error.enabled);
418}
419
420#ifdef FAULTHANDLER_LATER
421
422static void
423faulthandler_thread(void *unused)
424{
425 PyLockStatus st;
426 const char* errmsg;
427 PyThreadState *current;
428 int ok;
Victor Stinnercf2a8072011-04-19 23:30:57 +0200429#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Victor Stinnerda9edae2011-04-04 11:05:21 +0200430 sigset_t set;
431
432 /* we don't want to receive any signal */
433 sigfillset(&set);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200434 pthread_sigmask(SIG_SETMASK, &set, NULL);
Victor Stinnerda9edae2011-04-04 11:05:21 +0200435#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200436
437 do {
438 st = PyThread_acquire_lock_timed(thread.cancel_event,
Victor Stinner94189322011-04-08 13:00:31 +0200439 thread.timeout_us, 0);
Victor Stinner024e37a2011-03-31 01:31:06 +0200440 if (st == PY_LOCK_ACQUIRED) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200441 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +0200442 break;
443 }
444 /* Timeout => dump traceback */
445 assert(st == PY_LOCK_FAILURE);
446
447 /* get the thread holding the GIL, NULL if no thread hold the GIL */
448 current = _Py_atomic_load_relaxed(&_PyThreadState_Current);
449
Victor Stinner56cb1252012-10-31 00:33:57 +0100450 write(thread.fd, thread.header, (int)thread.header_len);
Victor Stinnerc790a532011-04-08 13:39:59 +0200451
Victor Stinner024e37a2011-03-31 01:31:06 +0200452 errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current);
453 ok = (errmsg == NULL);
454
455 if (thread.exit)
456 _exit(1);
457 } while (ok && thread.repeat);
458
459 /* The only way out */
Victor Stinnerde10f402011-04-08 12:57:06 +0200460 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200461}
462
463static void
Georg Brandldeb92b52012-09-22 08:58:55 +0200464cancel_dump_traceback_later(void)
Victor Stinner024e37a2011-03-31 01:31:06 +0200465{
Victor Stinner410dd7d2011-05-11 20:56:08 +0200466 /* Notify cancellation */
Victor Stinnerde10f402011-04-08 12:57:06 +0200467 PyThread_release_lock(thread.cancel_event);
468
Victor Stinnera4d4f1b2011-04-01 03:00:05 +0200469 /* Wait for thread to join */
Victor Stinnerde10f402011-04-08 12:57:06 +0200470 PyThread_acquire_lock(thread.running, 1);
471 PyThread_release_lock(thread.running);
472
473 /* The main thread should always hold the cancel_event lock */
474 PyThread_acquire_lock(thread.cancel_event, 1);
475
Victor Stinner024e37a2011-03-31 01:31:06 +0200476 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200477 if (thread.header) {
478 free(thread.header);
479 thread.header = NULL;
480 }
481}
482
483static char*
484format_timeout(double timeout)
485{
486 unsigned long us, sec, min, hour;
487 double intpart, fracpart;
488 char buffer[100];
489
490 fracpart = modf(timeout, &intpart);
491 sec = (unsigned long)intpart;
492 us = (unsigned long)(fracpart * 1e6);
493 min = sec / 60;
494 sec %= 60;
495 hour = min / 60;
496 min %= 60;
497
498 if (us != 0)
499 PyOS_snprintf(buffer, sizeof(buffer),
500 "Timeout (%lu:%02lu:%02lu.%06lu)!\n",
501 hour, min, sec, us);
502 else
503 PyOS_snprintf(buffer, sizeof(buffer),
504 "Timeout (%lu:%02lu:%02lu)!\n",
505 hour, min, sec);
506
507 return strdup(buffer);
Victor Stinner024e37a2011-03-31 01:31:06 +0200508}
509
510static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200511faulthandler_dump_traceback_later(PyObject *self,
Victor Stinner96994402011-04-07 11:37:19 +0200512 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200513{
514 static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
515 double timeout;
Victor Stinner94189322011-04-08 13:00:31 +0200516 PY_TIMEOUT_T timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200517 int repeat = 0;
518 PyObject *file = NULL;
519 int fd;
520 int exit = 0;
Victor Stinner96994402011-04-07 11:37:19 +0200521 PyThreadState *tstate;
Victor Stinnerc790a532011-04-08 13:39:59 +0200522 char *header;
523 size_t header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200524
525 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Georg Brandldeb92b52012-09-22 08:58:55 +0200526 "d|iOi:dump_traceback_later", kwlist,
Victor Stinner024e37a2011-03-31 01:31:06 +0200527 &timeout, &repeat, &file, &exit))
528 return NULL;
Victor Stinnerc790a532011-04-08 13:39:59 +0200529 if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200530 PyErr_SetString(PyExc_OverflowError, "timeout value is too large");
531 return NULL;
532 }
Victor Stinnerc790a532011-04-08 13:39:59 +0200533 timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
Victor Stinner94189322011-04-08 13:00:31 +0200534 if (timeout_us <= 0) {
Victor Stinner024e37a2011-03-31 01:31:06 +0200535 PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
536 return NULL;
537 }
538
Victor Stinnera4de6d82011-04-09 00:47:23 +0200539 tstate = get_thread_state();
540 if (tstate == NULL)
Victor Stinner96994402011-04-07 11:37:19 +0200541 return NULL;
Victor Stinner96994402011-04-07 11:37:19 +0200542
Victor Stinner024e37a2011-03-31 01:31:06 +0200543 file = faulthandler_get_fileno(file, &fd);
544 if (file == NULL)
545 return NULL;
546
Victor Stinnerc790a532011-04-08 13:39:59 +0200547 /* format the timeout */
548 header = format_timeout(timeout);
549 if (header == NULL)
550 return PyErr_NoMemory();
551 header_len = strlen(header);
552
Victor Stinner024e37a2011-03-31 01:31:06 +0200553 /* Cancel previous thread, if running */
Georg Brandldeb92b52012-09-22 08:58:55 +0200554 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200555
556 Py_XDECREF(thread.file);
557 Py_INCREF(file);
558 thread.file = file;
559 thread.fd = fd;
Victor Stinner94189322011-04-08 13:00:31 +0200560 thread.timeout_us = timeout_us;
Victor Stinner024e37a2011-03-31 01:31:06 +0200561 thread.repeat = repeat;
Victor Stinner96994402011-04-07 11:37:19 +0200562 thread.interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200563 thread.exit = exit;
Victor Stinnerc790a532011-04-08 13:39:59 +0200564 thread.header = header;
565 thread.header_len = header_len;
Victor Stinner024e37a2011-03-31 01:31:06 +0200566
567 /* Arm these locks to serve as events when released */
Victor Stinnerde10f402011-04-08 12:57:06 +0200568 PyThread_acquire_lock(thread.running, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +0200569
Victor Stinner024e37a2011-03-31 01:31:06 +0200570 if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
Victor Stinnerde10f402011-04-08 12:57:06 +0200571 PyThread_release_lock(thread.running);
Victor Stinner024e37a2011-03-31 01:31:06 +0200572 Py_CLEAR(thread.file);
Victor Stinnerc790a532011-04-08 13:39:59 +0200573 free(header);
574 thread.header = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200575 PyErr_SetString(PyExc_RuntimeError,
576 "unable to start watchdog thread");
577 return NULL;
578 }
579
580 Py_RETURN_NONE;
581}
582
583static PyObject*
Georg Brandldeb92b52012-09-22 08:58:55 +0200584faulthandler_cancel_dump_traceback_later_py(PyObject *self)
Victor Stinner024e37a2011-03-31 01:31:06 +0200585{
Georg Brandldeb92b52012-09-22 08:58:55 +0200586 cancel_dump_traceback_later();
Victor Stinner024e37a2011-03-31 01:31:06 +0200587 Py_RETURN_NONE;
588}
Victor Stinner410dd7d2011-05-11 20:56:08 +0200589#endif /* FAULTHANDLER_LATER */
Victor Stinner024e37a2011-03-31 01:31:06 +0200590
591#ifdef FAULTHANDLER_USER
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200592static int
593faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous)
594{
595#ifdef HAVE_SIGACTION
596 struct sigaction action;
597 action.sa_handler = faulthandler_user;
598 sigemptyset(&action.sa_mask);
599 /* if the signal is received while the kernel is executing a system
600 call, try to restart the system call instead of interrupting it and
601 return EINTR. */
602 action.sa_flags = SA_RESTART;
603 if (chain) {
604 /* do not prevent the signal from being received from within its
605 own signal handler */
606 action.sa_flags = SA_NODEFER;
607 }
608#ifdef HAVE_SIGALTSTACK
609 if (stack.ss_sp != NULL) {
610 /* Call the signal handler on an alternate signal stack
611 provided by sigaltstack() */
612 action.sa_flags |= SA_ONSTACK;
613 }
614#endif
615 return sigaction(signum, &action, p_previous);
616#else
617 _Py_sighandler_t previous;
618 previous = signal(signum, faulthandler_user);
619 if (p_previous != NULL)
620 *p_previous = previous;
621 return (previous == SIG_ERR);
622#endif
623}
624
Victor Stinner024e37a2011-03-31 01:31:06 +0200625/* Handler of user signals (e.g. SIGUSR1).
626
627 Dump the traceback of the current thread, or of all threads if
628 thread.all_threads is true.
629
630 This function is signal safe and should only call signal safe functions. */
631
632static void
633faulthandler_user(int signum)
634{
635 user_signal_t *user;
636 PyThreadState *tstate;
Victor Stinnerc9256172011-05-07 12:20:11 +0200637 int save_errno = errno;
Victor Stinner024e37a2011-03-31 01:31:06 +0200638
639 user = &user_signals[signum];
640 if (!user->enabled)
641 return;
642
Victor Stinnerff4cd882011-04-07 11:50:25 +0200643#ifdef WITH_THREAD
Victor Stinner024e37a2011-03-31 01:31:06 +0200644 /* PyThreadState_Get() doesn't give the state of the current thread if
645 the thread doesn't hold the GIL. Read the thread local storage (TLS)
646 instead: call PyGILState_GetThisThreadState(). */
647 tstate = PyGILState_GetThisThreadState();
Victor Stinnerff4cd882011-04-07 11:50:25 +0200648#else
649 tstate = PyThreadState_Get();
650#endif
Victor Stinner024e37a2011-03-31 01:31:06 +0200651
652 if (user->all_threads)
Victor Stinner44378d42011-04-01 15:37:12 +0200653 _Py_DumpTracebackThreads(user->fd, user->interp, tstate);
654 else {
Victor Stinner98a387b2012-08-01 19:36:36 +0200655 if (tstate != NULL)
656 _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);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200661 errno = save_errno;
662
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200663 /* call the previous signal handler */
664 raise(signum);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200665
666 save_errno = errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200667 (void)faulthandler_register(signum, user->chain, NULL);
Victor Stinner3cc635d2012-08-09 02:43:41 +0200668 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200669 }
670#else
671 if (user->chain) {
Victor Stinner3cc635d2012-08-09 02:43:41 +0200672 errno = save_errno;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200673 /* call the previous signal handler */
674 user->previous(signum);
675 }
676#endif
Victor Stinner44378d42011-04-01 15:37:12 +0200677}
678
679static int
680check_signum(int signum)
681{
682 unsigned int i;
683
684 for (i=0; i < faulthandler_nsignals; i++) {
685 if (faulthandler_handlers[i].signum == signum) {
686 PyErr_Format(PyExc_RuntimeError,
687 "signal %i cannot be registered, "
688 "use enable() instead",
689 signum);
690 return 0;
691 }
692 }
693 if (signum < 1 || NSIG <= signum) {
694 PyErr_SetString(PyExc_ValueError, "signal number out of range");
695 return 0;
696 }
697 return 1;
Victor Stinner024e37a2011-03-31 01:31:06 +0200698}
699
700static PyObject*
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200701faulthandler_register_py(PyObject *self,
702 PyObject *args, PyObject *kwargs)
Victor Stinner024e37a2011-03-31 01:31:06 +0200703{
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200704 static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
Victor Stinner024e37a2011-03-31 01:31:06 +0200705 int signum;
706 PyObject *file = NULL;
Victor Stinner7bba62f2011-05-07 12:43:00 +0200707 int all_threads = 1;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200708 int chain = 0;
Victor Stinner024e37a2011-03-31 01:31:06 +0200709 int fd;
Victor Stinner024e37a2011-03-31 01:31:06 +0200710 user_signal_t *user;
711 _Py_sighandler_t previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200712 PyThreadState *tstate;
Victor Stinner024e37a2011-03-31 01:31:06 +0200713 int err;
714
715 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200716 "i|Oii:register", kwlist,
717 &signum, &file, &all_threads, &chain))
Victor Stinner024e37a2011-03-31 01:31:06 +0200718 return NULL;
719
Victor Stinner44378d42011-04-01 15:37:12 +0200720 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200721 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200722
Victor Stinnera4de6d82011-04-09 00:47:23 +0200723 tstate = get_thread_state();
724 if (tstate == NULL)
Victor Stinner44378d42011-04-01 15:37:12 +0200725 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200726
727 file = faulthandler_get_fileno(file, &fd);
728 if (file == NULL)
729 return NULL;
730
731 if (user_signals == NULL) {
732 user_signals = calloc(NSIG, sizeof(user_signal_t));
733 if (user_signals == NULL)
734 return PyErr_NoMemory();
735 }
736 user = &user_signals[signum];
737
738 if (!user->enabled) {
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200739 err = faulthandler_register(signum, chain, &previous);
Victor Stinner024e37a2011-03-31 01:31:06 +0200740 if (err) {
741 PyErr_SetFromErrno(PyExc_OSError);
742 return NULL;
743 }
744 }
745
746 Py_XDECREF(user->file);
747 Py_INCREF(file);
748 user->file = file;
749 user->fd = fd;
750 user->all_threads = all_threads;
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200751 user->chain = chain;
Victor Stinner024e37a2011-03-31 01:31:06 +0200752 user->previous = previous;
Victor Stinner44378d42011-04-01 15:37:12 +0200753 user->interp = tstate->interp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200754 user->enabled = 1;
755
756 Py_RETURN_NONE;
757}
758
759static int
760faulthandler_unregister(user_signal_t *user, int signum)
761{
Victor Stinnera01ca122011-04-01 12:56:17 +0200762 if (!user->enabled)
Victor Stinner024e37a2011-03-31 01:31:06 +0200763 return 0;
764 user->enabled = 0;
765#ifdef HAVE_SIGACTION
766 (void)sigaction(signum, &user->previous, NULL);
767#else
768 (void)signal(signum, user->previous);
769#endif
770 Py_CLEAR(user->file);
771 user->fd = -1;
772 return 1;
773}
774
775static PyObject*
776faulthandler_unregister_py(PyObject *self, PyObject *args)
777{
778 int signum;
779 user_signal_t *user;
780 int change;
781
782 if (!PyArg_ParseTuple(args, "i:unregister", &signum))
783 return NULL;
784
Victor Stinner44378d42011-04-01 15:37:12 +0200785 if (!check_signum(signum))
Victor Stinner024e37a2011-03-31 01:31:06 +0200786 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200787
Victor Stinnercfa71232011-04-08 12:48:15 +0200788 if (user_signals == NULL)
789 Py_RETURN_FALSE;
790
Victor Stinner024e37a2011-03-31 01:31:06 +0200791 user = &user_signals[signum];
792 change = faulthandler_unregister(user, signum);
793 return PyBool_FromLong(change);
794}
795#endif /* FAULTHANDLER_USER */
796
797
798static PyObject *
799faulthandler_read_null(PyObject *self, PyObject *args)
800{
Victor Stinnera2477202012-01-30 00:07:43 +0100801 volatile int *x;
802 volatile int y;
Victor Stinner024e37a2011-03-31 01:31:06 +0200803 int release_gil = 0;
804 if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil))
805 return NULL;
Victor Stinnera2477202012-01-30 00:07:43 +0100806
807 x = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200808 if (release_gil) {
809 Py_BEGIN_ALLOW_THREADS
810 y = *x;
811 Py_END_ALLOW_THREADS
812 } else
813 y = *x;
814 return PyLong_FromLong(y);
815
816}
817
818static PyObject *
819faulthandler_sigsegv(PyObject *self, PyObject *args)
820{
821#if defined(MS_WINDOWS)
Victor Stinnerbc6a4db2011-04-01 12:08:57 +0200822 /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal
823 handler and then gives back the execution flow to the program (without
Victor Stinner410dd7d2011-05-11 20:56:08 +0200824 explicitly calling the previous error handler). In a normal case, the
Victor Stinner024e37a2011-03-31 01:31:06 +0200825 SIGSEGV was raised by the kernel because of a fault, and so if the
826 program retries to execute the same instruction, the fault will be
827 raised again.
828
829 Here the fault is simulated by a fake SIGSEGV signal raised by the
830 application. We have to raise SIGSEGV at lease twice: once for
831 faulthandler_fatal_error(), and one more time for the previous signal
832 handler. */
833 while(1)
834 raise(SIGSEGV);
835#else
836 raise(SIGSEGV);
837#endif
838 Py_RETURN_NONE;
839}
840
841static PyObject *
842faulthandler_sigfpe(PyObject *self, PyObject *args)
843{
844 /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on
845 PowerPC. Use volatile to disable compile-time optimizations. */
846 volatile int x = 1, y = 0, z;
847 z = x / y;
Victor Stinner410dd7d2011-05-11 20:56:08 +0200848 /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC),
849 raise it manually. */
Victor Stinner024e37a2011-03-31 01:31:06 +0200850 raise(SIGFPE);
Victor Stinner410dd7d2011-05-11 20:56:08 +0200851 /* This line is never reached, but we pretend to make something with z
852 to silence a compiler warning. */
Victor Stinnere0c9a752011-05-09 14:44:26 +0200853 return PyLong_FromLong(z);
Victor Stinner024e37a2011-03-31 01:31:06 +0200854}
855
Victor Stinnerd727e232011-04-01 12:13:55 +0200856static PyObject *
857faulthandler_sigabrt(PyObject *self, PyObject *args)
858{
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200859#ifdef _MSC_VER
860 /* Visual Studio: configure abort() to not display an error message nor
861 open a popup asking to report the fault. */
862 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
Victor Stinnerd727e232011-04-01 12:13:55 +0200863#endif
Victor Stinner00bc6cc2011-05-10 01:30:03 +0200864 abort();
Victor Stinnerd727e232011-04-01 12:13:55 +0200865 Py_RETURN_NONE;
866}
867
Victor Stinner024e37a2011-03-31 01:31:06 +0200868#ifdef SIGBUS
869static PyObject *
870faulthandler_sigbus(PyObject *self, PyObject *args)
871{
872 raise(SIGBUS);
873 Py_RETURN_NONE;
874}
875#endif
876
877#ifdef SIGILL
878static PyObject *
879faulthandler_sigill(PyObject *self, PyObject *args)
880{
Victor Stinner024e37a2011-03-31 01:31:06 +0200881 raise(SIGILL);
Victor Stinner024e37a2011-03-31 01:31:06 +0200882 Py_RETURN_NONE;
883}
884#endif
885
886static PyObject *
887faulthandler_fatal_error_py(PyObject *self, PyObject *args)
888{
889 char *message;
890 if (!PyArg_ParseTuple(args, "y:fatal_error", &message))
891 return NULL;
892 Py_FatalError(message);
893 Py_RETURN_NONE;
894}
895
896#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
Victor Stinner9b493042011-05-23 12:29:10 +0200897static void*
Victor Stinnerf0480752011-03-31 11:34:08 +0200898stack_overflow(void *min_sp, void *max_sp, size_t *depth)
Victor Stinner024e37a2011-03-31 01:31:06 +0200899{
900 /* allocate 4096 bytes on the stack at each call */
901 unsigned char buffer[4096];
Victor Stinnerf0480752011-03-31 11:34:08 +0200902 void *sp = &buffer;
903 *depth += 1;
904 if (sp < min_sp || max_sp < sp)
905 return sp;
Victor Stinner024e37a2011-03-31 01:31:06 +0200906 buffer[0] = 1;
Victor Stinnerf0480752011-03-31 11:34:08 +0200907 buffer[4095] = 0;
908 return stack_overflow(min_sp, max_sp, depth);
909}
910
911static PyObject *
912faulthandler_stack_overflow(PyObject *self)
913{
914 size_t depth, size;
Victor Stinner425fcd32011-09-07 16:18:56 +0200915 char *sp = (char *)&depth, *stop;
Victor Stinnerf0480752011-03-31 11:34:08 +0200916
917 depth = 0;
918 stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE,
919 sp + STACK_OVERFLOW_MAX_SIZE,
920 &depth);
921 if (sp < stop)
922 size = stop - sp;
923 else
924 size = sp - stop;
925 PyErr_Format(PyExc_RuntimeError,
926 "unable to raise a stack overflow (allocated %zu bytes "
927 "on the stack, %zu recursive calls)",
928 size, depth);
929 return NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +0200930}
931#endif
932
933
934static int
935faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
936{
937#ifdef FAULTHANDLER_USER
Victor Stinner96994402011-04-07 11:37:19 +0200938 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +0200939#endif
940
941#ifdef FAULTHANDLER_LATER
942 Py_VISIT(thread.file);
943#endif
944#ifdef FAULTHANDLER_USER
945 if (user_signals != NULL) {
Victor Stinner96994402011-04-07 11:37:19 +0200946 for (signum=0; signum < NSIG; signum++)
947 Py_VISIT(user_signals[signum].file);
Victor Stinner024e37a2011-03-31 01:31:06 +0200948 }
949#endif
950 Py_VISIT(fatal_error.file);
951 return 0;
952}
953
954PyDoc_STRVAR(module_doc,
955"faulthandler module.");
956
957static PyMethodDef module_methods[] = {
958 {"enable",
959 (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +0200960 PyDoc_STR("enable(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200961 "enable the fault handler")},
962 {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS,
963 PyDoc_STR("disable(): disable the fault handler")},
964 {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS,
965 PyDoc_STR("is_enabled()->bool: check if the handler is enabled")},
966 {"dump_traceback",
967 (PyCFunction)faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS,
Victor Stinner7bba62f2011-05-07 12:43:00 +0200968 PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200969 "dump the traceback of the current thread, or of all threads "
970 "if all_threads is True, into file")},
971#ifdef FAULTHANDLER_LATER
Georg Brandldeb92b52012-09-22 08:58:55 +0200972 {"dump_traceback_later",
973 (PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
974 PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
Victor Stinner024e37a2011-03-31 01:31:06 +0200975 "dump the traceback of all threads in timeout seconds,\n"
Victor Stinner96994402011-04-07 11:37:19 +0200976 "or each timeout seconds if repeat is True. If exit is True, "
977 "call _exit(1) which is not safe.")},
Georg Brandldeb92b52012-09-22 08:58:55 +0200978 {"cancel_dump_traceback_later",
979 (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
980 PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
981 "to dump_traceback_later().")},
Victor Stinner024e37a2011-03-31 01:31:06 +0200982#endif
983
984#ifdef FAULTHANDLER_USER
985 {"register",
Victor Stinnera9a9dab2011-07-13 23:39:53 +0200986 (PyCFunction)faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
987 PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): "
Victor Stinner024e37a2011-03-31 01:31:06 +0200988 "register an handler for the signal 'signum': dump the "
989 "traceback of the current thread, or of all threads if "
990 "all_threads is True, into file")},
991 {"unregister",
992 faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS,
993 PyDoc_STR("unregister(signum): unregister the handler of the signal "
994 "'signum' registered by register()")},
995#endif
996
997 {"_read_null", faulthandler_read_null, METH_VARARGS,
998 PyDoc_STR("_read_null(release_gil=False): read from NULL, raise "
999 "a SIGSEGV or SIGBUS signal depending on the platform")},
1000 {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
1001 PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")},
Victor Stinnerd727e232011-04-01 12:13:55 +02001002 {"_sigabrt", faulthandler_sigabrt, METH_VARARGS,
1003 PyDoc_STR("_sigabrt(): raise a SIGABRT signal")},
Victor Stinner024e37a2011-03-31 01:31:06 +02001004 {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS,
1005 PyDoc_STR("_sigfpe(): raise a SIGFPE signal")},
1006#ifdef SIGBUS
1007 {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS,
1008 PyDoc_STR("_sigbus(): raise a SIGBUS signal")},
1009#endif
1010#ifdef SIGILL
1011 {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS,
1012 PyDoc_STR("_sigill(): raise a SIGILL signal")},
1013#endif
1014 {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS,
1015 PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")},
1016#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1017 {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS,
1018 PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")},
1019#endif
Victor Stinner410dd7d2011-05-11 20:56:08 +02001020 {NULL, NULL} /* sentinel */
Victor Stinner024e37a2011-03-31 01:31:06 +02001021};
1022
1023static struct PyModuleDef module_def = {
1024 PyModuleDef_HEAD_INIT,
1025 "faulthandler",
1026 module_doc,
Victor Stinner410dd7d2011-05-11 20:56:08 +02001027 0, /* non-negative size to be able to unload the module */
Victor Stinner024e37a2011-03-31 01:31:06 +02001028 module_methods,
1029 NULL,
1030 faulthandler_traverse,
1031 NULL,
1032 NULL
1033};
1034
1035PyMODINIT_FUNC
1036PyInit_faulthandler(void)
1037{
1038 return PyModule_Create(&module_def);
1039}
1040
Victor Stinner410dd7d2011-05-11 20:56:08 +02001041/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
1042 is defined, or if sys._xoptions has a 'faulthandler' key. */
Victor Stinner024e37a2011-03-31 01:31:06 +02001043
1044static int
1045faulthandler_env_options(void)
1046{
1047 PyObject *xoptions, *key, *module, *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001048 _Py_IDENTIFIER(enable);
Victor Stinner024e37a2011-03-31 01:31:06 +02001049
1050 if (!Py_GETENV("PYTHONFAULTHANDLER")) {
Victor Stinner25095b22011-05-26 13:47:08 +02001051 int has_key;
1052
Victor Stinner024e37a2011-03-31 01:31:06 +02001053 xoptions = PySys_GetXOptions();
1054 if (xoptions == NULL)
1055 return -1;
1056
1057 key = PyUnicode_FromString("faulthandler");
1058 if (key == NULL)
1059 return -1;
1060
Victor Stinner25095b22011-05-26 13:47:08 +02001061 has_key = PyDict_Contains(xoptions, key);
Victor Stinner024e37a2011-03-31 01:31:06 +02001062 Py_DECREF(key);
Victor Stinner25095b22011-05-26 13:47:08 +02001063 if (!has_key)
Victor Stinner024e37a2011-03-31 01:31:06 +02001064 return 0;
1065 }
Victor Stinner024e37a2011-03-31 01:31:06 +02001066
1067 module = PyImport_ImportModule("faulthandler");
1068 if (module == NULL) {
1069 return -1;
1070 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001071 res = _PyObject_CallMethodId(module, &PyId_enable, "");
Victor Stinner024e37a2011-03-31 01:31:06 +02001072 Py_DECREF(module);
1073 if (res == NULL)
1074 return -1;
1075 Py_DECREF(res);
1076 return 0;
1077}
1078
1079int _PyFaulthandler_Init(void)
1080{
1081#ifdef HAVE_SIGALTSTACK
1082 int err;
1083
1084 /* Try to allocate an alternate stack for faulthandler() signal handler to
1085 * be able to allocate memory on the stack, even on a stack overflow. If it
1086 * fails, ignore the error. */
1087 stack.ss_flags = 0;
1088 stack.ss_size = SIGSTKSZ;
1089 stack.ss_sp = PyMem_Malloc(stack.ss_size);
1090 if (stack.ss_sp != NULL) {
1091 err = sigaltstack(&stack, NULL);
1092 if (err) {
1093 PyMem_Free(stack.ss_sp);
1094 stack.ss_sp = NULL;
1095 }
1096 }
1097#endif
1098#ifdef FAULTHANDLER_LATER
Victor Stinner024e37a2011-03-31 01:31:06 +02001099 thread.file = NULL;
1100 thread.cancel_event = PyThread_allocate_lock();
Victor Stinnerde10f402011-04-08 12:57:06 +02001101 thread.running = PyThread_allocate_lock();
1102 if (!thread.cancel_event || !thread.running) {
Victor Stinner024e37a2011-03-31 01:31:06 +02001103 PyErr_SetString(PyExc_RuntimeError,
1104 "could not allocate locks for faulthandler");
1105 return -1;
1106 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001107 PyThread_acquire_lock(thread.cancel_event, 1);
Victor Stinner024e37a2011-03-31 01:31:06 +02001108#endif
1109
1110 return faulthandler_env_options();
1111}
1112
1113void _PyFaulthandler_Fini(void)
1114{
1115#ifdef FAULTHANDLER_USER
Victor Stinnera01ca122011-04-01 12:56:17 +02001116 unsigned int signum;
Victor Stinner024e37a2011-03-31 01:31:06 +02001117#endif
1118
1119#ifdef FAULTHANDLER_LATER
1120 /* later */
Victor Stinner024e37a2011-03-31 01:31:06 +02001121 if (thread.cancel_event) {
Georg Brandldeb92b52012-09-22 08:58:55 +02001122 cancel_dump_traceback_later();
Victor Stinnerde10f402011-04-08 12:57:06 +02001123 PyThread_release_lock(thread.cancel_event);
Victor Stinner024e37a2011-03-31 01:31:06 +02001124 PyThread_free_lock(thread.cancel_event);
1125 thread.cancel_event = NULL;
1126 }
Victor Stinnerde10f402011-04-08 12:57:06 +02001127 if (thread.running) {
1128 PyThread_free_lock(thread.running);
1129 thread.running = NULL;
Victor Stinner024e37a2011-03-31 01:31:06 +02001130 }
1131#endif
1132
1133#ifdef FAULTHANDLER_USER
1134 /* user */
1135 if (user_signals != NULL) {
Victor Stinnera01ca122011-04-01 12:56:17 +02001136 for (signum=0; signum < NSIG; signum++)
1137 faulthandler_unregister(&user_signals[signum], signum);
Victor Stinner024e37a2011-03-31 01:31:06 +02001138 free(user_signals);
1139 user_signals = NULL;
1140 }
1141#endif
1142
1143 /* fatal */
1144 faulthandler_disable();
1145#ifdef HAVE_SIGALTSTACK
1146 if (stack.ss_sp != NULL) {
1147 PyMem_Free(stack.ss_sp);
1148 stack.ss_sp = NULL;
1149 }
1150#endif
1151}