Kaydet (Commit) a4de6d88 authored tarafından Victor Stinner's avatar Victor Stinner

Improve faulthandler.enable(all_threads=True)

faulthandler.enable(all_threads=True) dumps the tracebacks even if it is not
possible to get the state of the current thread

Create also the get_thread_state() subfunction to factorize the code.
üst c790a534
...@@ -40,6 +40,7 @@ static struct { ...@@ -40,6 +40,7 @@ static struct {
PyObject *file; PyObject *file;
int fd; int fd;
int all_threads; int all_threads;
PyInterpreterState *interp;
} fatal_error = {0, NULL, -1, 0}; } fatal_error = {0, NULL, -1, 0};
#ifdef FAULTHANDLER_LATER #ifdef FAULTHANDLER_LATER
...@@ -165,6 +166,20 @@ faulthandler_get_fileno(PyObject *file, int *p_fd) ...@@ -165,6 +166,20 @@ faulthandler_get_fileno(PyObject *file, int *p_fd)
return file; 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* static PyObject*
faulthandler_dump_traceback_py(PyObject *self, faulthandler_dump_traceback_py(PyObject *self,
PyObject *args, PyObject *kwargs) PyObject *args, PyObject *kwargs)
...@@ -185,13 +200,9 @@ faulthandler_dump_traceback_py(PyObject *self, ...@@ -185,13 +200,9 @@ faulthandler_dump_traceback_py(PyObject *self,
if (file == NULL) if (file == NULL)
return NULL; return NULL;
/* The caller holds the GIL and so PyThreadState_Get() can be used */ tstate = get_thread_state();
tstate = PyThreadState_Get(); if (tstate == NULL)
if (tstate == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"unable to get the current thread state");
return NULL; return NULL;
}
if (all_threads) { if (all_threads) {
errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate); errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
...@@ -266,13 +277,13 @@ faulthandler_fatal_error(int signum) ...@@ -266,13 +277,13 @@ faulthandler_fatal_error(int signum)
#else #else
tstate = PyThreadState_Get(); tstate = PyThreadState_Get();
#endif #endif
if (tstate == NULL)
return;
if (fatal_error.all_threads) if (fatal_error.all_threads)
_Py_DumpTracebackThreads(fd, tstate->interp, tstate); _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate);
else else {
_Py_DumpTraceback(fd, tstate); if (tstate != NULL)
_Py_DumpTraceback(fd, tstate);
}
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (signum == SIGSEGV) { if (signum == SIGSEGV) {
...@@ -301,6 +312,7 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -301,6 +312,7 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
#endif #endif
int err; int err;
int fd; int fd;
PyThreadState *tstate;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|Oi:enable", kwlist, &file, &all_threads)) "|Oi:enable", kwlist, &file, &all_threads))
...@@ -310,11 +322,16 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -310,11 +322,16 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
if (file == NULL) if (file == NULL)
return NULL; return NULL;
tstate = get_thread_state();
if (tstate == NULL)
return NULL;
Py_XDECREF(fatal_error.file); Py_XDECREF(fatal_error.file);
Py_INCREF(file); Py_INCREF(file);
fatal_error.file = file; fatal_error.file = file;
fatal_error.fd = fd; fatal_error.fd = fd;
fatal_error.all_threads = all_threads; fatal_error.all_threads = all_threads;
fatal_error.interp = tstate->interp;
if (!fatal_error.enabled) { if (!fatal_error.enabled) {
fatal_error.enabled = 1; fatal_error.enabled = 1;
...@@ -515,12 +532,9 @@ faulthandler_dump_tracebacks_later(PyObject *self, ...@@ -515,12 +532,9 @@ faulthandler_dump_tracebacks_later(PyObject *self,
return NULL; return NULL;
} }
tstate = PyThreadState_Get(); tstate = get_thread_state();
if (tstate == NULL) { if (tstate == NULL)
PyErr_SetString(PyExc_RuntimeError,
"unable to get the current thread state");
return NULL; return NULL;
}
file = faulthandler_get_fileno(file, &fd); file = faulthandler_get_fileno(file, &fd);
if (file == NULL) if (file == NULL)
...@@ -652,13 +666,9 @@ faulthandler_register(PyObject *self, ...@@ -652,13 +666,9 @@ faulthandler_register(PyObject *self,
if (!check_signum(signum)) if (!check_signum(signum))
return NULL; return NULL;
/* The caller holds the GIL and so PyThreadState_Get() can be used */ tstate = get_thread_state();
tstate = PyThreadState_Get(); if (tstate == NULL)
if (tstate == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"unable to get the current thread state");
return NULL; return NULL;
}
file = faulthandler_get_fileno(file, &fd); file = faulthandler_get_fileno(file, &fd);
if (file == NULL) if (file == NULL)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment