VirtualBox

Changeset 39535 in vbox for trunk/src/libs/xpcom18a4/python


Ignore:
Timestamp:
Dec 5, 2011 3:42:26 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
75219
Message:

xpcom/python: Some object life time debugging option (debug builds only).

Location:
trunk/src/libs/xpcom18a4/python
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/python/Makefile.kmk

    r39212 r39535  
    7272        VBOX_WITH_XPCOM \
    7373        VBOX_PYXPCOM_VERSIONED
     74VBoxPythonBase_DEFS.debug = \
     75        VBOX_DEBUG_LIFETIMES
    7476VBoxPythonBase_INCS     = \
    7577        src
  • trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp

    r16909 r39535  
    5050#include <nsIConsoleService.h>
    5151#ifdef VBOX
    52 #include <nsIExceptionService.h>
    53 #include <iprt/err.h>
     52# include <nsIExceptionService.h>
     53# include <iprt/err.h>
     54# include <iprt/string.h>
    5455#endif
    5556#include "nspr.h" // PR_fprintf
     
    148149{
    149150        char buff[512];
     151#ifdef VBOX /* Enable the use of VBox formatting types. */
     152        RTStrPrintfV(buff, sizeof(buff), fmt, argptr);
     153#else
    150154        // Use safer NS_ functions.
    151155        PR_vsnprintf(buff, sizeof(buff), fmt, argptr);
     156#endif
    152157
    153158        LogMessage(methodName, buff);
  • trunk/src/libs/xpcom18a4/python/src/PyIID.cpp

    r33977 r39535  
    6767                        if (size != sizeof(nsIID) || buf==NULL) {
    6868#ifdef VBOX
    69                                 PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %u bytes long", sizeof(nsIID));
     69                                PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", (int)sizeof(nsIID));
    7070#else
    7171                                PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", sizeof(nsIID));
  • trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp

    r33977 r39535  
    5252static PyObject *g_obFuncMakeInterfaceCount = NULL; // XXX - never released!!!
    5353
     54#ifdef VBOX_DEBUG_LIFETIMES
     55# include <iprt/log.h>
     56# include <iprt/stream.h>
     57
     58/*static*/ RTLISTNODE        Py_nsISupports::g_List;
     59/*static*/ RTONCE            Py_nsISupports::g_Once = RTONCE_INITIALIZER;
     60/*static*/ RTCRITSECT        Py_nsISupports::g_CritSect;
     61
     62/*static*/ DECLCALLBACK(int)
     63Py_nsISupports::initOnceCallback(void *pvUser1, void *pvUser2)
     64{
     65    NOREF(pvUser1); NOREF(pvUser2);
     66    RTListInit(&g_List);
     67    return RTCritSectInit(&g_CritSect);
     68}
     69
     70/*static*/ void
     71Py_nsISupports::dumpList(void)
     72{
     73    RTOnce(&g_Once, initOnceCallback, NULL, NULL);
     74    RTCritSectEnter(&g_CritSect);
     75
     76    uint32_t i = 0;
     77    Py_nsISupports *pCur;
     78    RTListForEach(&g_List, pCur, Py_nsISupports, m_ListEntry)
     79    {
     80        nsISupports *pISup = pCur->m_obj;
     81        PyXPCOM_LogWarning("#%u: %p iid=%RTuuid obj=%p", i, pCur, &pCur->m_iid, pISup);
     82        i++;
     83    }
     84
     85    RTCritSectLeave(&g_CritSect);
     86}
     87
     88/*static*/ void
     89Py_nsISupports::dumpListToStdOut()
     90{
     91    RTOnce(&g_Once, initOnceCallback, NULL, NULL);
     92    RTCritSectEnter(&g_CritSect);
     93
     94    uint32_t i = 0;
     95    Py_nsISupports *pCur;
     96    RTListForEach(&g_List, pCur, Py_nsISupports, m_ListEntry)
     97    {
     98        nsISupports *pISup = pCur->m_obj;
     99        RTPrintf("#%u: %p iid=%RTuuid obj=%p\n", i, pCur, &pCur->m_iid, pISup);
     100        i++;
     101    }
     102
     103    RTCritSectLeave(&g_CritSect);
     104}
     105
     106PRInt32
     107_PyXPCOM_DumpInterfaces(void)
     108{
     109        Py_nsISupports::dumpListToStdOut();
     110        return NS_OK;
     111}
     112
     113#endif /* _DEBUG_LIFETIMES */
     114
     115
     116
    54117PyObject *PyObject_FromNSInterface( nsISupports *aInterface,
    55118                                    const nsIID &iid,
     
    75138        PyXPCOM_DLLAddRef();
    76139        _Py_NewReference(this);
     140
     141#ifdef VBOX_DEBUG_LIFETIMES
     142        RTOnce(&g_Once, initOnceCallback, NULL, NULL);
     143        RTCritSectEnter(&g_CritSect);
     144        PyXPCOM_LogWarning("Creating   %p: iid=%RTuuid obj=%p", this, &m_iid, punk);
     145        RTListAppend(&g_List, &m_ListEntry);
     146        RTCritSectLeave(&g_CritSect);
     147#endif
    77148}
    78149
    79150Py_nsISupports::~Py_nsISupports()
    80151{
     152#ifdef VBOX_DEBUG_LIFETIMES
     153        RTCritSectEnter(&g_CritSect);
     154        nsISupports *punk = m_obj;
     155        PyXPCOM_LogWarning("Destroying %p: iid=%RTuuid obj=%p", this, &m_iid, punk);
     156        RTListNodeRemove(&m_ListEntry);
     157        RTCritSectLeave(&g_CritSect);
     158#endif
     159
    81160        SafeRelease(this);
    82161        PR_AtomicDecrement(&cInterfaces);
  • trunk/src/libs/xpcom18a4/python/src/PyXPCOM.h

    r32229 r39535  
    6666#include "xpt_xdr.h"
    6767
     68#ifdef VBOX_DEBUG_LIFETIMES
     69# include <iprt/critsect.h>
     70# include <iprt/list.h>
     71# include <iprt/once.h>
     72#endif
     73
    6874#ifdef HAVE_LONG_LONG
    6975        // Mozilla also defines this - we undefine it to
     
    7783
    7884#ifdef VBOX_PYXPCOM
    79 // unfortunatelly, if SOLARIS is defined Python porting layer 
     85// unfortunatelly, if SOLARIS is defined Python porting layer
    8086// defines gethostname() in invalid fashion what kills compilation
    8187# ifdef SOLARIS
     
    223229// Interfaces - these are the "official" functions
    224230PYXPCOM_EXPORT PyObject *PyObject_FromNSInterface( nsISupports *aInterface,
    225                                                    const nsIID &iid, 
     231                                                   const nsIID &iid,
    226232                                                   PRBool bMakeNicePyObject = PR_TRUE);
    227233
     
    242248class PYXPCOM_EXPORT PyXPCOM_TypeObject : public PyTypeObject {
    243249public:
    244         PyXPCOM_TypeObject( 
    245                 const char *name, 
    246                 PyXPCOM_TypeObject *pBaseType, 
    247                 int typeSize, 
     250        PyXPCOM_TypeObject(
     251                const char *name,
     252                PyXPCOM_TypeObject *pBaseType,
     253                int typeSize,
    248254                struct PyMethodDef* methodList,
    249255                PyXPCOM_I_CTOR ctor);
     
    304310        // optimization, but  since removed.  This function *always* takes a
    305311        // reference to the nsISupports.
    306         static PyObject *PyObjectFromInterface(nsISupports *ps, 
    307                                                const nsIID &iid, 
     312        static PyObject *PyObjectFromInterface(nsISupports *ps,
     313                                               const nsIID &iid,
    308314                                               PRBool bMakeNicePyObject = PR_TRUE,
    309315                                               PRBool bIsInternalCall = PR_FALSE);
     
    328334        // Object *must* be Py_nsISupports - there is no
    329335        // "autowrap", no "None" support, etc
    330         static PRBool InterfaceFromPyISupports(PyObject *ob, 
    331                                                const nsIID &iid, 
     336        static PRBool InterfaceFromPyISupports(PyObject *ob,
     337                                               const nsIID &iid,
    332338                                               nsISupports **ppv);
    333339
     
    343349        static void RegisterInterface( const nsIID &iid, PyTypeObject *t);
    344350        static void InitType();
     351#ifdef VBOX_DEBUG_LIFETIMES
     352        static void dumpList(void);
     353        static void dumpListToStdOut(void);
     354#endif
    345355
    346356        virtual ~Py_nsISupports();
     
    358368        // ctor is protected - must create objects via
    359369        // PyObjectFromInterface()
    360         Py_nsISupports(nsISupports *p, 
    361                             const nsIID &iid, 
     370        Py_nsISupports(nsISupports *p,
     371                            const nsIID &iid,
    362372                            PyTypeObject *type);
    363373
     
    366376        static PyObject *MakeDefaultWrapper(PyObject *pyis, const nsIID &iid);
    367377
    368 };
    369 
    370 // Python/XPCOM IID support
     378#ifdef VBOX_DEBUG_LIFETIMES
     379        static DECLCALLBACK(int) initOnceCallback(void *pvUser1, void *pvUser2);
     380
     381        RTLISTNODE              m_ListEntry; /**< List entry. */
     382
     383        static RTONCE           g_Once;      /**< Init list and critsect once. */
     384        static RTCRITSECT       g_CritSect;  /**< Critsect protecting the list. */
     385        static RTLISTANCHOR     g_List;      /**< List of live interfaces.*/
     386#endif
     387};
     388
     389// Python/XPCOM IID support
    371390class PYXPCOM_EXPORT Py_nsIID : public PyObject
    372391{
     
    375394        nsIID m_iid;
    376395
    377         PRBool 
     396        PRBool
    378397        IsEqual(const nsIID &riid) {
    379398                return m_iid.Equals(riid);
     
    382401        PRBool
    383402        IsEqual(PyObject *ob) {
    384                 return ob && 
    385                        ob->ob_type== &type && 
     403                return ob &&
     404                       ob->ob_type== &type &&
    386405                       m_iid.Equals(((Py_nsIID *)ob)->m_iid);
    387406        }
     
    459478// We also allow the underlying PyObject to be extracted
    460479class nsIInternalPython : public nsISupports {
    461 public: 
     480public:
    462481        NS_DEFINE_STATIC_IID_ACCESSOR(NS_IINTERNALPYTHON_IID)
    463482        // Get the underlying Python object with new reference added
     
    475494
    476495        // A static "constructor" - the real ctor is protected.
    477         static nsresult CreateNew(PyObject *pPyInstance, 
    478                                   const nsIID &iid, 
     496        static nsresult CreateNew(PyObject *pPyInstance,
     497                                  const nsIID &iid,
    479498                                  void **ppResult);
    480499
    481         // A utility to auto-wrap an arbitary Python instance 
     500        // A utility to auto-wrap an arbitary Python instance
    482501        // in a COM gateway.
    483         static PRBool AutoWrapPythonInstance(PyObject *ob, 
    484                                            const nsIID &iid, 
     502        static PRBool AutoWrapPythonInstance(PyObject *ob,
     503                                           const nsIID &iid,
    485504                                           nsISupports **ppret);
    486505
     
    488507        // A helper that creates objects to be passed for nsISupports
    489508        // objects.  See extensive comments in PyG_Base.cpp.
    490         PyObject *MakeInterfaceParam(nsISupports *pis, 
    491                                              const nsIID *piid, 
     509        PyObject *MakeInterfaceParam(nsISupports *pis,
     510                                             const nsIID *piid,
    492511                                             int methodIndex = -1,
    493                                              const XPTParamDescriptor *d = NULL, 
     512                                             const XPTParamDescriptor *d = NULL,
    494513                                             int paramIndex = -1);
    495514
     
    570589extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetGatewayCount(void);
    571590extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetInterfaceCount(void);
     591#ifdef VBOX_DEBUG_LIFETIMES
     592extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_DumpInterfaces(void);
     593#endif
    572594
    573595
     
    578600// object dies due to XPCOM reference counting, it zaps the pointer
    579601// in its corresponding weak reference object.  Thus, the weak-reference
    580 // can live beyond the object (possibly with a NULL pointer back to the 
    581 // "real" object, but as implemented, the weak reference will never be 
     602// can live beyond the object (possibly with a NULL pointer back to the
     603// "real" object, but as implemented, the weak reference will never be
    582604// destroyed  before the object
    583605class PYXPCOM_EXPORT PyXPCOM_GatewayWeakReference : public nsIWeakReference {
     
    600622        PyXPCOM_GatewayVariantHelper( PyG_Base *gateway,
    601623                                      int methodIndex,
    602                                       const nsXPTMethodInfo *info, 
     624                                      const nsXPTMethodInfo *info,
    603625                                      nsXPTCMiniVariant* params );
    604626        ~PyXPCOM_GatewayVariantHelper();
     
    627649// Misc converters.
    628650PyObject *PyObject_FromXPTType( const nsXPTType *d);
    629 // XPTTypeDescriptor derived from XPTType - latter is automatically processed via PyObject_FromXPTTypeDescriptor XPTTypeDescriptor 
     651// XPTTypeDescriptor derived from XPTType - latter is automatically processed via PyObject_FromXPTTypeDescriptor XPTTypeDescriptor
    630652PyObject *PyObject_FromXPTTypeDescriptor( const XPTTypeDescriptor *d);
    631653
     
    655677// first having this thread lock.
    656678//
    657 // The second type of lock is a "global framework lock", and used whenever 2 threads 
    658 // of C code need access to global data.  This is different than the Python 
    659 // lock - this lock is used when no Python code can ever be called by the 
     679// The second type of lock is a "global framework lock", and used whenever 2 threads
     680// of C code need access to global data.  This is different than the Python
     681// lock - this lock is used when no Python code can ever be called by the
    660682// threads, but the C code still needs thread-safety.
    661683
     
    669691//
    670692// This class magically waits for PyXPCOM framework global lock, and releases it
    671 // when finished. 
     693// when finished.
    672694// NEVER new one of these objects - only use on the stack!
    673695class CEnterLeaveXPCOMFramework {
     
    684706//
    685707// This class magically waits for the Python global lock, and releases it
    686 // when finished. 
     708// when finished.
    687709
    688710// Nested invocations will deadlock, so be careful.
     
    749771        // _before_ we release the lock, as some of
    750772        // the sys. attributes cleared (eg, the current exception)
    751         // may need the lock to invoke their destructors - 
     773        // may need the lock to invoke their destructors -
    752774        // specifically, when exc_value is a class instance, and
    753775        // the exception holds the last reference!
  • trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp

    r38636 r39535  
    5555#include "nspr.h" // PR_fprintf
    5656#ifdef VBOX
    57 #include "nsEventQueueUtils.h"
     57# include "nsEventQueueUtils.h"
    5858#endif
    5959
     
    319319}
    320320
     321#ifdef VBOX_DEBUG_LIFETIMES
     322// @pymethod int|pythoncom|_DumpInterfaces|Dumps the interfaces still in existance to standard output
     323static PyObject *
     324PyXPCOMMethod_DumpInterfaces(PyObject *self, PyObject *args)
     325{
     326        if (!PyArg_ParseTuple(args, ":_DumpInterfaces"))
     327                return NULL;
     328        return PyInt_FromLong(_PyXPCOM_DumpInterfaces());
     329}
     330#endif
     331
    321332// @pymethod int|pythoncom|_GetGatewayCount|Retrieves the number of gateway objects currently in existance
    322333static PyObject *
     
    343354        nr = NS_ShutdownXPCOM(nsnull);
    344355        Py_END_ALLOW_THREADS;
     356
     357#ifdef VBOX_DEBUG_LIFETIME
     358        Py_nsISupports::dumpList();
     359#endif
    345360
    346361        // Dont raise an exception - as we are probably shutting down
     
    661676        {"DetachThread",  PyXPCOMMethod_DetachThread, 1},
    662677#endif
     678#ifdef VBOX_DEBUG_LIFETIMES
     679        {"_DumpInterfaces", PyXPCOMMethod_DumpInterfaces, 1},
     680#endif
    663681        // These should no longer be used - just use the logging.getLogger('pyxpcom')...
     682        /* bird: The above comment refers to LogWarning and LogError. Both now removed. */
    664683        { NULL }
    665684};
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette