PyObject *file;
int fd;
int all_threads;
+ PyInterpreterState *interp;
} fatal_error = {0, NULL, -1, 0};
#ifdef FAULTHANDLER_LATER
return file;
}
+/* Get the state of the current thread: only call this function if the current
+ thread holds the GIL. Raise an exception on error. */
+static PyThreadState*
+get_thread_state(void)
+{
+ PyThreadState *tstate = PyThreadState_Get();
+ if (tstate == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "unable to get the current thread state");
+ return NULL;
+ }
+ return tstate;
+}
+
static PyObject*
faulthandler_dump_traceback_py(PyObject *self,
PyObject *args, PyObject *kwargs)
if (file == NULL)
return NULL;
- /* The caller holds the GIL and so PyThreadState_Get() can be used */
- tstate = PyThreadState_Get();
- if (tstate == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "unable to get the current thread state");
+ tstate = get_thread_state();
+ if (tstate == NULL)
return NULL;
- }
if (all_threads) {
errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
#else
tstate = PyThreadState_Get();
#endif
- if (tstate == NULL)
- return;
if (fatal_error.all_threads)
- _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
- else
- _Py_DumpTraceback(fd, tstate);
+ _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate);
+ else {
+ if (tstate != NULL)
+ _Py_DumpTraceback(fd, tstate);
+ }
#ifdef MS_WINDOWS
if (signum == SIGSEGV) {
#endif
int err;
int fd;
+ PyThreadState *tstate;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|Oi:enable", kwlist, &file, &all_threads))
if (file == NULL)
return NULL;
+ tstate = get_thread_state();
+ if (tstate == NULL)
+ return NULL;
+
Py_XDECREF(fatal_error.file);
Py_INCREF(file);
fatal_error.file = file;
fatal_error.fd = fd;
fatal_error.all_threads = all_threads;
+ fatal_error.interp = tstate->interp;
if (!fatal_error.enabled) {
fatal_error.enabled = 1;
return NULL;
}
- tstate = PyThreadState_Get();
- if (tstate == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "unable to get the current thread state");
+ tstate = get_thread_state();
+ if (tstate == NULL)
return NULL;
- }
file = faulthandler_get_fileno(file, &fd);
if (file == NULL)
if (!check_signum(signum))
return NULL;
- /* The caller holds the GIL and so PyThreadState_Get() can be used */
- tstate = PyThreadState_Get();
- if (tstate == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "unable to get the current thread state");
+ tstate = get_thread_state();
+ if (tstate == NULL)
return NULL;
- }
file = faulthandler_get_fileno(file, &fd);
if (file == NULL)