Browse Source

pipeline: Fix crash upon exception in custom thread

We can't call PyErr_Restore() without a valid thread state, which won't exist in a custom thread if we just called PyGILState_Release().  Not sure how this has ever worked.
rdb 4 years ago
parent
commit
bdb2ef1631
2 changed files with 8 additions and 1 deletions
  1. 5 0
      dtool/src/interrogatedb/py_compat.h
  2. 3 1
      panda/src/pipeline/pythonThread.cxx

+ 5 - 0
dtool/src/interrogatedb/py_compat.h

@@ -137,6 +137,11 @@ typedef long Py_hash_t;
 #  endif
 #  endif
 #endif
 #endif
 
 
+/* Python 3.4 */
+#if PY_VERSION_HEX < 0x03040000
+#define PyGILState_Check() (PyGILState_GetThisThreadState() == _PyThreadState_Current)
+#endif
+
 /* Python 3.6 */
 /* Python 3.6 */
 
 
 #if PY_VERSION_HEX < 0x03080000 && !defined(_PyObject_CallNoArg)
 #if PY_VERSION_HEX < 0x03080000 && !defined(_PyObject_CallNoArg)

+ 3 - 1
panda/src/pipeline/pythonThread.cxx

@@ -258,7 +258,9 @@ call_python_func(PyObject *function, PyObject *args) {
 
 
       PyGILState_Release(gstate);
       PyGILState_Release(gstate);
 
 
-      PyErr_Restore(exc, val, tb);
+      if (PyGILState_Check()) {
+        PyErr_Restore(exc, val, tb);
+      }
     } else {
     } else {
       // No exception.  Restore the thread state normally.
       // No exception.  Restore the thread state normally.
       PyGILState_Release(gstate);
       PyGILState_Release(gstate);