[Python-checkins] cpython: Improve faulthandler.enable(all_threads=True)

victor.stinner python-checkins at python.org
Sat Apr 9 00:51:27 CEST 2011


http://hg.python.org/cpython/rev/78a66c98288d
changeset:   69209:78a66c98288d
user:        Victor Stinner <victor.stinner at haypocalc.com>
date:        Sat Apr 09 00:47:23 2011 +0200
summary:
  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.

files:
  Modules/faulthandler.c |  54 +++++++++++++++++------------
  1 files changed, 32 insertions(+), 22 deletions(-)


diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -40,6 +40,7 @@
     PyObject *file;
     int fd;
     int all_threads;
+    PyInterpreterState *interp;
 } fatal_error = {0, NULL, -1, 0};
 
 #ifdef FAULTHANDLER_LATER
@@ -165,6 +166,20 @@
     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)
@@ -185,13 +200,9 @@
     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);
@@ -266,13 +277,13 @@
 #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) {
@@ -301,6 +312,7 @@
 #endif
     int err;
     int fd;
+    PyThreadState *tstate;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
         "|Oi:enable", kwlist, &file, &all_threads))
@@ -310,11 +322,16 @@
     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;
@@ -515,12 +532,9 @@
         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)
@@ -652,13 +666,9 @@
     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)

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list