From bee3d11f62a9752d6c51cef510c9ab2e9cf6dc26 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 10 Mar 2023 23:45:37 +0100 Subject: [PATCH] [consider merging] avoid an assertion in the Python exit code for accessing an already destroyed Python object --- src/pya/pya/pyaInternal.cc | 8 ++++++++ src/pya/pya/pyaInternal.h | 1 + src/pya/pya/pyaRefs.cc | 7 +++++++ src/pya/pya/pyaRefs.h | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/src/pya/pya/pyaInternal.cc b/src/pya/pya/pyaInternal.cc index cfd04e4a6..ec5e6c0e4 100644 --- a/src/pya/pya/pyaInternal.cc +++ b/src/pya/pya/pyaInternal.cc @@ -859,6 +859,14 @@ PythonClassClientData::PythonClassClientData (const gsi::ClassBase *_cls, PyType // .. nothing yet .. } +PythonClassClientData::~PythonClassClientData () +{ + // This destructor is called from the exit code. Python may have shut down already. + // We must not try to release the objects in that case and simply don't care about them any longer. + py_type_object.release (); + py_type_object_static.release (); +} + PyTypeObject * PythonClassClientData::py_type (const gsi::ClassBase &cls_decl, bool as_static) { diff --git a/src/pya/pya/pyaInternal.h b/src/pya/pya/pyaInternal.h index 5cea68417..92b227252 100644 --- a/src/pya/pya/pyaInternal.h +++ b/src/pya/pya/pyaInternal.h @@ -302,6 +302,7 @@ struct PythonClassClientData : public gsi::PerClassClientSpecificData { PythonClassClientData (const gsi::ClassBase *_cls, PyTypeObject *_py_type, PyTypeObject *_py_type_static, PythonModule *module); + ~PythonClassClientData (); PythonPtr py_type_object; PythonPtr py_type_object_static; diff --git a/src/pya/pya/pyaRefs.cc b/src/pya/pya/pyaRefs.cc index 764fc548b..536a5829e 100644 --- a/src/pya/pya/pyaRefs.cc +++ b/src/pya/pya/pyaRefs.cc @@ -151,6 +151,13 @@ PythonPtr::~PythonPtr () Py_XDECREF (mp_obj); } +PyObject *PythonPtr::release () +{ + PyObject *obj = mp_obj; + mp_obj = NULL; + return obj; +} + PythonPtr::operator bool () const { return mp_obj != NULL; diff --git a/src/pya/pya/pyaRefs.h b/src/pya/pya/pyaRefs.h index 16ecaa39a..86668960f 100644 --- a/src/pya/pya/pyaRefs.h +++ b/src/pya/pya/pyaRefs.h @@ -211,6 +211,14 @@ public: return mp_obj < other.mp_obj; } + /** + * @brief Releases the object + * + * This method returns and resets the raw pointer without changing the + * reference count. + */ + PyObject *release (); + private: PyObject *mp_obj; };