From: Andreas Monzner Date: Sun, 26 Nov 2006 13:10:35 +0000 (+0000) Subject: more python refcount debugging stuff X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=e5f1c45c07b1ff43c0113a51128f60bd3e348aa4 more python refcount debugging stuff --- diff --git a/configure.ac b/configure.ac index 0ab8dd7..e9af324 100644 --- a/configure.ac +++ b/configure.ac @@ -40,7 +40,7 @@ fi CPPFLAGS="$CPPFLAGS "'-I$(top_srcdir)' CPPFLAGS="$CPPFLAGS -D_REENTRANT $PYTHON_CPPFLAGS $MD5SUM_CFLAGS $FREETYPE_CFLAGS $FRIBIDI_CFLAGS $ID3TAG_CFLAGS $MAD_CFLAGS $PLUGINS_CFLAGS $PNG_CFLAGS $SDL_CFLAGS $SIGC_CFLAGS $XMLTREE_CFLAGS $DVBSI_CFLAGS $GSTREAMER_CFLAGS" -CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions -Wall" +CXXFLAGS="$CXXFLAGS -DPYTHON_REFCOUNT_DEBUG -fno-rtti -fno-exceptions -Wall" LDFLAGS="$LDFLAGS -pthread $PYTHON_LDFLAGS $SDL_LDFLAGS $GSTREAMER_LDFLAGS" TUXBOX_APPS_GETTEXT diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index 7cd56b9..6adab39 100644 --- a/lib/dvb/epgcache.cpp +++ b/lib/dvb/epgcache.cpp @@ -1535,22 +1535,22 @@ void fillTuple(ePyObject tuple, char *argstring, int argcount, ePyObject service tmp = PyLong_FromLong(0); break; case 'I': // Event Id - tmp = ptr ? PyLong_FromLong(ptr->getEventId()) : NULL; + tmp = ptr ? PyLong_FromLong(ptr->getEventId()) : ePyObject(); break; case 'B': // Event Begin Time - tmp = ptr ? PyLong_FromLong(ptr->getBeginTime()) : NULL; + tmp = ptr ? PyLong_FromLong(ptr->getBeginTime()) : ePyObject(); break; case 'D': // Event Duration - tmp = ptr ? PyLong_FromLong(ptr->getDuration()) : NULL; + tmp = ptr ? PyLong_FromLong(ptr->getDuration()) : ePyObject(); break; case 'T': // Event Title - tmp = ptr ? PyString_FromString(ptr->getEventName().c_str()) : NULL; + tmp = ptr ? PyString_FromString(ptr->getEventName().c_str()) : ePyObject(); break; case 'S': // Event Short Description - tmp = ptr ? PyString_FromString(ptr->getShortDescription().c_str()) : NULL; + tmp = ptr ? PyString_FromString(ptr->getShortDescription().c_str()) : ePyObject(); break; case 'E': // Event Extended Description - tmp = ptr ? PyString_FromString(ptr->getExtendedDescription().c_str()) : NULL; + tmp = ptr ? PyString_FromString(ptr->getExtendedDescription().c_str()) : ePyObject(); break; case 'C': // Current Time tmp = nowTime; @@ -1581,7 +1581,7 @@ int handleEvent(ePtr &ptr, ePyObject dest_list, char* argstring, { fillTuple(convertFuncArgs, argstring, argcount, service, ptr, nowTime, service_name); ePyObject result = PyObject_CallObject(convertFunc, convertFuncArgs); - if (result == NULL) + if (result) { if (service_name) Py_DECREF(service_name); @@ -1679,7 +1679,7 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc) ePyObject nowTime = strchr(argstring, 'C') ? PyLong_FromLong(eDVBLocalTimeHandler::getInstance()->nowTime()) : - NULL; + ePyObject(); bool must_get_service_name = strchr(argstring, 'N') ? true : false; @@ -1838,24 +1838,24 @@ void fillTuple2(ePyObject tuple, const char *argstring, int argcount, eventData break; case 'B': // Event Begin Time if (ptr) - tmp = ptr ? PyLong_FromLong(ptr->getBeginTime()) : NULL; + tmp = ptr ? PyLong_FromLong(ptr->getBeginTime()) : ePyObject(); else tmp = PyLong_FromLong(evData->getStartTime()); break; case 'D': // Event Duration if (ptr) - tmp = ptr ? PyLong_FromLong(ptr->getDuration()) : NULL; + tmp = ptr ? PyLong_FromLong(ptr->getDuration()) : ePyObject(); else tmp = PyLong_FromLong(evData->getDuration()); break; case 'T': // Event Title - tmp = ptr ? PyString_FromString(ptr->getEventName().c_str()) : NULL; + tmp = ptr ? PyString_FromString(ptr->getEventName().c_str()) : ePyObject(); break; case 'S': // Event Short Description - tmp = ptr ? PyString_FromString(ptr->getShortDescription().c_str()) : NULL; + tmp = ptr ? PyString_FromString(ptr->getShortDescription().c_str()) : ePyObject(); break; case 'E': // Event Extended Description - tmp = ptr ? PyString_FromString(ptr->getExtendedDescription().c_str()) : NULL; + tmp = ptr ? PyString_FromString(ptr->getExtendedDescription().c_str()) : ePyObject(); break; case 'R': // service reference string tmp = service_reference; diff --git a/lib/gui/epositiongauge.cpp b/lib/gui/epositiongauge.cpp index fbb2457..a7608b7 100644 --- a/lib/gui/epositiongauge.cpp +++ b/lib/gui/epositiongauge.cpp @@ -70,14 +70,14 @@ void ePositionGauge::setInOutList(ePyObject list) for (i=0; i, ePtr >::iterator it(m_recordings.begin()); it != m_recordings.end(); ++it) - PyList_SET_ITEM(result, pos++, New_iRecordableServicePtr(it->first)); + PyList_SET_ITEM(result, pos++, NEW_iRecordableServicePtr(it->first)); return result; } diff --git a/lib/python/python.h b/lib/python/python.h index bcea49c..42749c7 100644 --- a/lib/python/python.h +++ b/lib/python/python.h @@ -8,8 +8,6 @@ #include #include -#define PYTHON_REFCOUNT_DEBUG - #if !defined(SKIP_PART1) && !defined(SWIG) class ePyObject { @@ -23,10 +21,14 @@ public: inline ePyObject(); inline ePyObject(const ePyObject &ob); inline ePyObject(PyObject *ob); +#ifdef PYTHON_REFCOUNT_DEBUG + inline ePyObject(PyObject *ob, const char *file, int line); +#endif inline ePyObject(PyDictObject *ob); inline ePyObject(PyTupleObject *ob); inline ePyObject(PyListObject *ob); inline ePyObject(PyStringObject *ob); + operator bool() const { return !!m_ob; } operator bool() { return !!m_ob; } ePyObject &operator=(const ePyObject &); ePyObject &operator=(PyObject *); @@ -74,6 +76,14 @@ inline ePyObject::ePyObject(PyObject *ob) { } +#ifdef PYTHON_REFCOUNT_DEBUG +inline ePyObject::ePyObject(PyObject *ob, const char* file, int line) + :m_ob(ob) + ,m_file(file), m_line(line), m_from(ob->ob_refcnt), m_to(ob->ob_refcnt), m_erased(false) +{ +} +#endif + inline ePyObject::ePyObject(PyDictObject *ob) :m_ob((PyObject*)ob) #ifdef PYTHON_REFCOUNT_DEBUG @@ -149,10 +159,8 @@ public: }; TEMPLATE_TYPEDEF(ePtr, TestObjPtr); -extern PyObject *New_TestObj(); - #ifndef SWIG - +extern PyObject *New_TestObj(); #ifdef PYTHON_REFCOUNT_DEBUG inline void Impl_Py_DECREF(const char* file, int line, const ePyObject &obj) { @@ -175,6 +183,61 @@ inline void Impl_Py_XINCREF(const char* file, int line, const ePyObject &obj) if (obj) ((ePyObject*)(&obj))->incref(file, line); } + +inline ePyObject Impl_PyTuple_New(const char* file, int line, int elements=0) +{ + return ePyObject(PyTuple_New(elements), file, line); +} + +inline ePyObject Impl_PyList_New(const char* file, int line, int elements=0) +{ + return ePyObject(PyList_New(elements), file, line); +} + +inline ePyObject Impl_PyDict_New(const char* file, int line) +{ + return ePyObject(PyDict_New(), file, line); +} + +inline ePyObject Impl_PyString_FromString(const char* file, int line, const char *str) +{ + return ePyObject(PyString_FromString(str), file, line); +} + +inline ePyObject Impl_PyInt_FromLong(const char* file, int line, long val) +{ + return ePyObject(PyInt_FromLong(val), file, line); +} + +inline ePyObject Impl_PyLong_FromLong(const char* file, int line, long val) +{ + return ePyObject(PyLong_FromLong(val), file, line); +} + +inline ePyObject Impl_PyLong_FromUnsignedLong(const char* file, int line, unsigned long val) +{ + return ePyObject(PyLong_FromUnsignedLong(val), file, line); +} + +inline ePyObject Impl_PyLong_FromLongLong(const char* file, int line, long long val) +{ + return ePyObject(PyLong_FromLongLong(val), file, line); +} + +inline ePyObject Impl_New_TestObj(const char* file, int line) +{ + return ePyObject(New_TestObj(), file, line); +} + +inline ePyObject Impl_PyList_GET_ITEM(const char *file, int line, ePyObject list, unsigned int pos) +{ + return ePyObject(PyList_GET_ITEM(list, pos), file, line); +} + +inline ePyObject Impl_PyTuple_GET_ITEM(const char *file, int line, ePyObject list, unsigned int pos) +{ + return ePyObject(PyTuple_GET_ITEM(list, pos), file, line); +} #else inline void Impl_Py_DECREF(const ePyObject &obj) { @@ -197,6 +260,61 @@ inline void Impl_Py_XINCREF(const ePyObject &obj) if (obj) ((ePyObject*)(&obj))->incref(); } + +inline ePyObject Impl_PyTuple_New(int elements=0) +{ + return PyTuple_New(elements); +} + +inline ePyObject Impl_PyList_New(int elements=0) +{ + return PyList_New(elements); +} + +inline ePyObject Impl_PyDict_New() +{ + return PyDict_New(); +} + +inline ePyObject Impl_PyString_FromString(const char *str) +{ + return PyString_FromString(str); +} + +inline ePyObject Impl_PyInt_FromLong(long val) +{ + return PyInt_FromLong(val); +} + +inline ePyObject Impl_PyLong_FromLong(long val) +{ + return PyLong_FromLong(val); +} + +inline ePyObject Impl_PyLong_FromUnsignedLong(unsigned long val) +{ + return PyLong_FromUnsignedLong(val); +} + +inline ePyObject Impl_PyLong_FromLongLong(long long val) +{ + return PyLong_FromLongLong(val); +} + +inline ePyObject Impl_New_TestObj() +{ + return New_TestObj(); +} + +inline ePyObject Impl_PyList_GET_ITEM(ePyObject list, unsigned int pos) +{ + return PyList_GET_ITEM(list, pos); +} + +inline ePyObject Impl_PyTuple_GET_ITEM(ePyObject list, unsigned int pos) +{ + return PyTuple_GET_ITEM(list, pos); +} #endif inline void Impl_DECREF(PyObject *ob) @@ -208,16 +326,40 @@ inline void Impl_DECREF(PyObject *ob) #undef Py_XDECREF #undef Py_INCREF #undef Py_XINCREF +#undef PyList_GET_ITEM +#undef PyTuple_GET_ITEM #ifdef PYTHON_REFCOUNT_DEBUG #define Py_DECREF(obj) Impl_Py_DECREF(__FILE__, __LINE__, obj) #define Py_XDECREF(obj) Impl_Py_XDECREF(__FILE__, __LINE__, obj) #define Py_INCREF(obj) Impl_Py_INCREF(__FILE__, __LINE__, obj) #define Py_XINCREF(obj) Impl_Py_XINCREF(__FILE__, __LINE__, obj) +#define PyList_New(args...) Impl_PyList_New(__FILE__, __LINE__, args) +#define PyTuple_New(args...) Impl_PyTuple_New(__FILE__, __LINE__, args) +#define PyDict_New(...) Impl_PyDict_New(__FILE__, __LINE__) +#define PyString_FromString(str) Impl_PyString_FromString(__FILE__, __LINE__, str) +#define PyInt_FromLong(val) Impl_PyInt_FromLong(__FILE__, __LINE__, val) +#define PyLong_FromLong(val) Impl_PyLong_FromLong(__FILE__, __LINE__, val) +#define PyLong_FromUnsignedLong(val) Impl_PyLong_FromUnsignedLong(__FILE__, __LINE__, val) +#define PyLong_FromLongLong(val) Impl_PyLong_FromLongLong(__FILE__, __LINE__, val) +#define NEW_TestObj(...) Impl_New_TestObj(__FILE__, __LINE__) +#define PyList_GET_ITEM(list, pos) Impl_PyList_GET_ITEM(__FILE__, __LINE__, list, pos) +#define PyTuple_GET_ITEM(list, pos) Impl_PyTuple_GET_ITEM(__FILE__, __LINE__, list, pos) #else #define Py_DECREF(obj) Impl_Py_DECREF(obj) #define Py_XDECREF(obj) Impl_Py_XDECREF(obj) #define Py_INCREF(obj) Impl_Py_INCREF(obj) #define Py_XINCREF(obj) Impl_Py_XINCREF(obj) +#define PyList_New(args...) Impl_PyList_New(args) +#define PyTuple_New(args...) Impl_PyTuple_New(args) +#define PyDict_New(...) Impl_PyDict_New() +#define PyString_FromString(str) Impl_PyString_FromString(str) +#define PyInt_FromLong(val) Impl_PyInt_FromLong(val) +#define PyLong_FromLong(val) Impl_PyLong_FromLong(val) +#define PyLong_FromUnsignedLong(val) Impl_PyLong_FromUnsignedLong(val) +#define PyLong_FromLongLong(val) Impl_PyLong_FromLongLong(val) +#define NEW_TestObj(...) Impl_New_TestObj() +#define PyList_GET_ITEM(list, pos) Impl_PyList_GET_ITEM(list, pos) +#define PyTuple_GET_ITEM(list, pos) Impl_PyTuple_GET_ITEM(list, pos) #endif class ePython diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 25935b2..0d11dd7 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -184,6 +184,22 @@ SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference); extern PyObject *New_eServiceReference(const eServiceReference &ref); // defined in enigma_python.i +#ifndef SWIG +#ifdef PYTHON_REFCOUNT_DEBUG +inline ePyObject Impl_New_eServiceReference(const char* file, int line, const eServiceReference &ref) +{ + return ePyObject(New_eServiceReference(ref), file, line); +} +#define NEW_eServiceReference(ref) Impl_New_eServiceReference(__FILE__, __LINE__, ref) +#else +inline ePyObject Impl_New_eServiceReference(const eServiceReference &ref) +{ + return New_eServiceReference(ref); +} +#define NEW_eServiceReference(ref) Impl_New_eServiceReference(ref) +#endif +#endif // SWIG + typedef long long pts_t; /* the reason we have the servicereference as additional argument is @@ -582,6 +598,22 @@ inline PyObject *PyFrom(ePtr &c) return New_iRecordableServicePtr(c); } +#ifndef SWIG +#ifdef PYTHON_REFCOUNT_DEBUG +inline ePyObject Impl_New_iRecordableServicePtr(const char* file, int line, const ePtr &ptr) +{ + return ePyObject(New_iRecordableServicePtr(ptr), file, line); +} +#define NEW_iRecordableServicePtr(ptr) Impl_New_iRecordableServicePtr(__FILE__, __LINE__, ptr) +#else +inline ePyObject Impl_New_iRecordableServicePtr(const ePtr &ptr) +{ + return New_iRecordableServicePtr(ptr); +} +#define NEW_iRecordableServicePtr(ptr) Impl_New_iRecordableServicePtr(ptr) +#endif +#endif // SWIG + // TEMPLATE_TYPEDEF(std::list, eServiceReferenceList); class iMutableServiceList: public iObject diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 627ccec..871a0b2 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -428,14 +428,14 @@ PyObject *eDVBServiceList::getContent(const char* format, bool sorted) for (int cnt=0; cnt < services; ++cnt) { eServiceReference &ref=*it++; - ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : 0; + ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject(); for (int i=0; i < retcount; ++i) { ePyObject tmp; switch(format[i]) { case 'R': // service reference (swig)object - tmp = New_eServiceReference(ref); + tmp = NEW_eServiceReference(ref); break; case 'C': // service reference compare string tmp = PyString_FromString(ref.toCompareString().c_str()); @@ -1551,7 +1551,7 @@ void eDVBServicePlay::setCutList(ePyObject list) for (i=0; i 1 ? PyTuple_New(retcount) : 0; + ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject(); for (int i=0; i < retcount; ++i) { ePyObject tmp; switch(format[i]) { case 'R': // service reference (swig)object - tmp = New_eServiceReference(ref); + tmp = NEW_eServiceReference(ref); break; case 'C': // service reference compare string tmp = PyString_FromString(ref.toCompareString().c_str());