From 5829cbbf60529448e63e5b7103a007d08d9387d8 Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Tue, 10 Jul 2018 12:27:15 +0200 Subject: Fix limited API incompatibility with Python 3.7 When Python 3.7 appeared, the structure of pystate.h was changed, substantially. Unfortunately this structure contains the trashcan code, which is only available as a macro and not part of the limited API. This code is normally not used by application programs. It prevents crashes when chains of millions of objects are deallocated. I disabled this for now when the limited API is active. As soon as somebody complains about crashes, I will try to implement it again in a safe way, but I am not sure if it is worth it in the first place. Task-number: PYSIDE-737 Change-Id: Id0daf391448ddcb9df3d299f859ef024714fa736 Reviewed-by: Friedemann Kleint --- sources/shiboken2/libshiboken/basewrapper.cpp | 4 ++ sources/shiboken2/libshiboken/pep384impl.h | 77 --------------------------- sources/shiboken2/libshiboken/sbkenum.cpp | 4 ++ 3 files changed, 8 insertions(+), 77 deletions(-) (limited to 'sources/shiboken2/libshiboken') diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index ae6b2a68a..122e60e41 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -259,7 +259,9 @@ void SbkObjectTypeDealloc(PyObject* pyObj) PyTypeObject *type = reinterpret_cast(pyObj); PyObject_GC_UnTrack(pyObj); +#ifndef Py_LIMITED_API Py_TRASHCAN_SAFE_BEGIN(pyObj); +#endif if (sotp) { if (sotp->user_data && sotp->d_func) { sotp->d_func(sotp->user_data); @@ -272,7 +274,9 @@ void SbkObjectTypeDealloc(PyObject* pyObj) delete sotp; sotp = nullptr; } +#ifndef Py_LIMITED_API Py_TRASHCAN_SAFE_END(pyObj); +#endif } PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds) diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h index d5b0c7654..8f14c853a 100644 --- a/sources/shiboken2/libshiboken/pep384impl.h +++ b/sources/shiboken2/libshiboken/pep384impl.h @@ -286,83 +286,6 @@ typedef struct _pycfunc PyCFunctionObject; typedef struct _methoddescr PyMethodDescrObject; #endif -/***************************************************************************** - * - * RESOLVED: pystate.h - * - */ - -/* - * pystate provides the data structure that is needed for the trashcan - * algorithm. Unfortunately, it is not included in the limited API. - * We have two options: - * - * (1) ignore trashcan and live without secured deeply nested structures, - * (2) maintain the structure ourselves and make sure it does not change. - * - * I have chosen the second option. - * - * When a new python version appears, you need to check compatibility of - * the PyThreadState structure (pystate.h) and the trashcan macros at the - * end of object.h . - */ - -#ifdef Py_LIMITED_API - -#define Py_TRASH_MIN_COMPATIBLE 0x03020400 -#define Py_TRASH_MAX_COMPATIBLE 0x0307FFFF - -#if PY_VERSION_HEX >= Py_TRASH_MIN_COMPATIBLE && \ - PY_VERSION_HEX <= Py_TRASH_MAX_COMPATIBLE -typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); - -// This structure has the trashcan variables since Python 3.2.4. -// We renamed all but the trashcan fields to make sure that we don't use -// anything else somewhere. - -typedef struct _ts { - struct _ts *Pep_prev; - struct _ts *Pep_next; - PyInterpreterState *Pep_interp; - - struct _frame *Pep_frame; - int Pep_recursion_depth; - char Pep_overflowed; - char Pep_recursion_critical; - - int Pep_tracing; - int Pep_use_tracing; - - Py_tracefunc Pep_c_profilefunc; - Py_tracefunc Pep_c_tracefunc; - PyObject *Pep_c_profileobj; - PyObject *Pep_c_traceobj; - - PyObject *Pep_curexc_type; - PyObject *Pep_curexc_value; - PyObject *Pep_curexc_traceback; - - PyObject *Pep_exc_type; - PyObject *Pep_exc_value; - PyObject *Pep_exc_traceback; - - PyObject *Pep_dict; - - int Pep_gilstate_counter; - - PyObject *Pep_async_exc; - long Pep_thread_id; - // These two variables only are of interest to us. - int trash_delete_nesting; - PyObject *trash_delete_later; - // Here we cut away the rest of the reduced structure. -} PyThreadState; -#else -#error *** Please check compatibility of the trashcan code, see Pep.h *** -#endif - -#endif // Py_LIMITED_API - /***************************************************************************** * * RESOLVED: pythonrun.h diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp index 5f753293c..119591215 100644 --- a/sources/shiboken2/libshiboken/sbkenum.cpp +++ b/sources/shiboken2/libshiboken/sbkenum.cpp @@ -312,11 +312,15 @@ void SbkEnumTypeDealloc(PyObject* pyObj) SbkEnumType* sbkType = reinterpret_cast(pyObj); PyObject_GC_UnTrack(pyObj); +#ifndef Py_LIMITED_API Py_TRASHCAN_SAFE_BEGIN(pyObj); +#endif if (PepType_SETP(sbkType)->converter) { Shiboken::Conversions::deleteConverter(PepType_SETP(sbkType)->converter); } +#ifndef Py_LIMITED_API Py_TRASHCAN_SAFE_END(pyObj); +#endif } PyObject* SbkEnumTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds) -- cgit v1.2.3