Index: trunk/src/libs/xpcom18a4/python/Makefile.kmk
===================================================================
--- trunk/src/libs/xpcom18a4/python/Makefile.kmk	(revision 39534)
+++ trunk/src/libs/xpcom18a4/python/Makefile.kmk	(revision 39535)
@@ -72,4 +72,6 @@
 	VBOX_WITH_XPCOM \
 	VBOX_PYXPCOM_VERSIONED
+VBoxPythonBase_DEFS.debug = \
+	VBOX_DEBUG_LIFETIMES
 VBoxPythonBase_INCS     = \
 	src
Index: trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp	(revision 39534)
+++ trunk/src/libs/xpcom18a4/python/src/ErrorUtils.cpp	(revision 39535)
@@ -50,6 +50,7 @@
 #include <nsIConsoleService.h>
 #ifdef VBOX
-#include <nsIExceptionService.h>
-#include <iprt/err.h>
+# include <nsIExceptionService.h>
+# include <iprt/err.h>
+# include <iprt/string.h>
 #endif
 #include "nspr.h" // PR_fprintf
@@ -148,6 +149,10 @@
 {
 	char buff[512];
+#ifdef VBOX /* Enable the use of VBox formatting types. */
+	RTStrPrintfV(buff, sizeof(buff), fmt, argptr);
+#else
 	// Use safer NS_ functions.
 	PR_vsnprintf(buff, sizeof(buff), fmt, argptr);
+#endif
 
 	LogMessage(methodName, buff);
Index: trunk/src/libs/xpcom18a4/python/src/PyIID.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/python/src/PyIID.cpp	(revision 39534)
+++ trunk/src/libs/xpcom18a4/python/src/PyIID.cpp	(revision 39535)
@@ -67,5 +67,5 @@
 			if (size != sizeof(nsIID) || buf==NULL) {
 #ifdef VBOX
-                                PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %u bytes long", sizeof(nsIID));
+                                PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", (int)sizeof(nsIID));
 #else
 				PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", sizeof(nsIID));
Index: trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp	(revision 39534)
+++ trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp	(revision 39535)
@@ -52,4 +52,67 @@
 static PyObject *g_obFuncMakeInterfaceCount = NULL; // XXX - never released!!!
 
+#ifdef VBOX_DEBUG_LIFETIMES
+# include <iprt/log.h>
+# include <iprt/stream.h>
+
+/*static*/ RTLISTNODE        Py_nsISupports::g_List;
+/*static*/ RTONCE            Py_nsISupports::g_Once = RTONCE_INITIALIZER;
+/*static*/ RTCRITSECT        Py_nsISupports::g_CritSect;
+
+/*static*/ DECLCALLBACK(int)
+Py_nsISupports::initOnceCallback(void *pvUser1, void *pvUser2)
+{
+    NOREF(pvUser1); NOREF(pvUser2);
+    RTListInit(&g_List);
+    return RTCritSectInit(&g_CritSect);
+}
+
+/*static*/ void
+Py_nsISupports::dumpList(void)
+{
+    RTOnce(&g_Once, initOnceCallback, NULL, NULL);
+    RTCritSectEnter(&g_CritSect);
+
+    uint32_t i = 0;
+    Py_nsISupports *pCur;
+    RTListForEach(&g_List, pCur, Py_nsISupports, m_ListEntry)
+    {
+	nsISupports *pISup = pCur->m_obj;
+	PyXPCOM_LogWarning("#%u: %p iid=%RTuuid obj=%p", i, pCur, &pCur->m_iid, pISup);
+	i++;
+    }
+
+    RTCritSectLeave(&g_CritSect);
+}
+
+/*static*/ void
+Py_nsISupports::dumpListToStdOut()
+{
+    RTOnce(&g_Once, initOnceCallback, NULL, NULL);
+    RTCritSectEnter(&g_CritSect);
+
+    uint32_t i = 0;
+    Py_nsISupports *pCur;
+    RTListForEach(&g_List, pCur, Py_nsISupports, m_ListEntry)
+    {
+	nsISupports *pISup = pCur->m_obj;
+	RTPrintf("#%u: %p iid=%RTuuid obj=%p\n", i, pCur, &pCur->m_iid, pISup);
+	i++;
+    }
+
+    RTCritSectLeave(&g_CritSect);
+}
+
+PRInt32
+_PyXPCOM_DumpInterfaces(void)
+{
+	Py_nsISupports::dumpListToStdOut();
+	return NS_OK;
+}
+
+#endif /* _DEBUG_LIFETIMES */
+
+
+
 PyObject *PyObject_FromNSInterface( nsISupports *aInterface,
                                     const nsIID &iid,
@@ -75,8 +138,24 @@
 	PyXPCOM_DLLAddRef();
 	_Py_NewReference(this);
+
+#ifdef VBOX_DEBUG_LIFETIMES
+        RTOnce(&g_Once, initOnceCallback, NULL, NULL);
+        RTCritSectEnter(&g_CritSect);
+	PyXPCOM_LogWarning("Creating   %p: iid=%RTuuid obj=%p", this, &m_iid, punk);
+        RTListAppend(&g_List, &m_ListEntry);
+        RTCritSectLeave(&g_CritSect);
+#endif
 }
 
 Py_nsISupports::~Py_nsISupports()
 {
+#ifdef VBOX_DEBUG_LIFETIMES
+	RTCritSectEnter(&g_CritSect);
+	nsISupports *punk = m_obj;
+	PyXPCOM_LogWarning("Destroying %p: iid=%RTuuid obj=%p", this, &m_iid, punk);
+	RTListNodeRemove(&m_ListEntry);
+	RTCritSectLeave(&g_CritSect);
+#endif
+
 	SafeRelease(this);
 	PR_AtomicDecrement(&cInterfaces);
Index: trunk/src/libs/xpcom18a4/python/src/PyXPCOM.h
===================================================================
--- trunk/src/libs/xpcom18a4/python/src/PyXPCOM.h	(revision 39534)
+++ trunk/src/libs/xpcom18a4/python/src/PyXPCOM.h	(revision 39535)
@@ -66,4 +66,10 @@
 #include "xpt_xdr.h"
 
+#ifdef VBOX_DEBUG_LIFETIMES
+# include <iprt/critsect.h>
+# include <iprt/list.h>
+# include <iprt/once.h>
+#endif
+
 #ifdef HAVE_LONG_LONG
 	// Mozilla also defines this - we undefine it to
@@ -77,5 +83,5 @@
 
 #ifdef VBOX_PYXPCOM
-// unfortunatelly, if SOLARIS is defined Python porting layer 
+// unfortunatelly, if SOLARIS is defined Python porting layer
 // defines gethostname() in invalid fashion what kills compilation
 # ifdef SOLARIS
@@ -223,5 +229,5 @@
 // Interfaces - these are the "official" functions
 PYXPCOM_EXPORT PyObject *PyObject_FromNSInterface( nsISupports *aInterface,
-                                                   const nsIID &iid, 
+                                                   const nsIID &iid,
                                                    PRBool bMakeNicePyObject = PR_TRUE);
 
@@ -242,8 +248,8 @@
 class PYXPCOM_EXPORT PyXPCOM_TypeObject : public PyTypeObject {
 public:
-	PyXPCOM_TypeObject( 
-		const char *name, 
-		PyXPCOM_TypeObject *pBaseType, 
-		int typeSize, 
+	PyXPCOM_TypeObject(
+		const char *name,
+		PyXPCOM_TypeObject *pBaseType,
+		int typeSize,
 		struct PyMethodDef* methodList,
 		PyXPCOM_I_CTOR ctor);
@@ -304,6 +310,6 @@
 	// optimization, but  since removed.  This function *always* takes a
 	// reference to the nsISupports.
-	static PyObject *PyObjectFromInterface(nsISupports *ps, 
-	                                       const nsIID &iid, 
+	static PyObject *PyObjectFromInterface(nsISupports *ps,
+	                                       const nsIID &iid,
 	                                       PRBool bMakeNicePyObject = PR_TRUE,
 	                                       PRBool bIsInternalCall = PR_FALSE);
@@ -328,6 +334,6 @@
 	// Object *must* be Py_nsISupports - there is no
 	// "autowrap", no "None" support, etc
-	static PRBool InterfaceFromPyISupports(PyObject *ob, 
-	                                       const nsIID &iid, 
+	static PRBool InterfaceFromPyISupports(PyObject *ob,
+	                                       const nsIID &iid,
 	                                       nsISupports **ppv);
 
@@ -343,4 +349,8 @@
 	static void RegisterInterface( const nsIID &iid, PyTypeObject *t);
 	static void InitType();
+#ifdef VBOX_DEBUG_LIFETIMES
+	static void dumpList(void);
+	static void dumpListToStdOut(void);
+#endif
 
 	virtual ~Py_nsISupports();
@@ -358,6 +368,6 @@
 	// ctor is protected - must create objects via
 	// PyObjectFromInterface()
-	Py_nsISupports(nsISupports *p, 
-		            const nsIID &iid, 
+	Py_nsISupports(nsISupports *p,
+		            const nsIID &iid,
 			    PyTypeObject *type);
 
@@ -366,7 +376,16 @@
 	static PyObject *MakeDefaultWrapper(PyObject *pyis, const nsIID &iid);
 
-};
-
-// Python/XPCOM IID support 
+#ifdef VBOX_DEBUG_LIFETIMES
+	static DECLCALLBACK(int) initOnceCallback(void *pvUser1, void *pvUser2);
+
+	RTLISTNODE              m_ListEntry; /**< List entry. */
+
+	static RTONCE           g_Once;      /**< Init list and critsect once. */
+	static RTCRITSECT       g_CritSect;  /**< Critsect protecting the list. */
+	static RTLISTANCHOR     g_List;      /**< List of live interfaces.*/
+#endif
+};
+
+// Python/XPCOM IID support
 class PYXPCOM_EXPORT Py_nsIID : public PyObject
 {
@@ -375,5 +394,5 @@
 	nsIID m_iid;
 
-	PRBool 
+	PRBool
 	IsEqual(const nsIID &riid) {
 		return m_iid.Equals(riid);
@@ -382,6 +401,6 @@
 	PRBool
 	IsEqual(PyObject *ob) {
-		return ob && 
-		       ob->ob_type== &type && 
+		return ob &&
+		       ob->ob_type== &type &&
 		       m_iid.Equals(((Py_nsIID *)ob)->m_iid);
 	}
@@ -459,5 +478,5 @@
 // We also allow the underlying PyObject to be extracted
 class nsIInternalPython : public nsISupports {
-public: 
+public:
 	NS_DEFINE_STATIC_IID_ACCESSOR(NS_IINTERNALPYTHON_IID)
 	// Get the underlying Python object with new reference added
@@ -475,12 +494,12 @@
 
 	// A static "constructor" - the real ctor is protected.
-	static nsresult CreateNew(PyObject *pPyInstance, 
-		                  const nsIID &iid, 
+	static nsresult CreateNew(PyObject *pPyInstance,
+		                  const nsIID &iid,
 				  void **ppResult);
 
-	// A utility to auto-wrap an arbitary Python instance 
+	// A utility to auto-wrap an arbitary Python instance
 	// in a COM gateway.
-	static PRBool AutoWrapPythonInstance(PyObject *ob, 
-		                           const nsIID &iid, 
+	static PRBool AutoWrapPythonInstance(PyObject *ob,
+		                           const nsIID &iid,
 					   nsISupports **ppret);
 
@@ -488,8 +507,8 @@
 	// A helper that creates objects to be passed for nsISupports
 	// objects.  See extensive comments in PyG_Base.cpp.
-	PyObject *MakeInterfaceParam(nsISupports *pis, 
-	                                     const nsIID *piid, 
+	PyObject *MakeInterfaceParam(nsISupports *pis,
+	                                     const nsIID *piid,
 					     int methodIndex = -1,
-					     const XPTParamDescriptor *d = NULL, 
+					     const XPTParamDescriptor *d = NULL,
 					     int paramIndex = -1);
 
@@ -570,4 +589,7 @@
 extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetGatewayCount(void);
 extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetInterfaceCount(void);
+#ifdef VBOX_DEBUG_LIFETIMES
+extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_DumpInterfaces(void);
+#endif
 
 
@@ -578,6 +600,6 @@
 // object dies due to XPCOM reference counting, it zaps the pointer
 // in its corresponding weak reference object.  Thus, the weak-reference
-// can live beyond the object (possibly with a NULL pointer back to the 
-// "real" object, but as implemented, the weak reference will never be 
+// can live beyond the object (possibly with a NULL pointer back to the
+// "real" object, but as implemented, the weak reference will never be
 // destroyed  before the object
 class PYXPCOM_EXPORT PyXPCOM_GatewayWeakReference : public nsIWeakReference {
@@ -600,5 +622,5 @@
 	PyXPCOM_GatewayVariantHelper( PyG_Base *gateway,
 	                              int methodIndex,
-	                              const nsXPTMethodInfo *info, 
+	                              const nsXPTMethodInfo *info,
 	                              nsXPTCMiniVariant* params );
 	~PyXPCOM_GatewayVariantHelper();
@@ -627,5 +649,5 @@
 // Misc converters.
 PyObject *PyObject_FromXPTType( const nsXPTType *d);
-// XPTTypeDescriptor derived from XPTType - latter is automatically processed via PyObject_FromXPTTypeDescriptor XPTTypeDescriptor 
+// XPTTypeDescriptor derived from XPTType - latter is automatically processed via PyObject_FromXPTTypeDescriptor XPTTypeDescriptor
 PyObject *PyObject_FromXPTTypeDescriptor( const XPTTypeDescriptor *d);
 
@@ -655,7 +677,7 @@
 // first having this thread lock.
 //
-// The second type of lock is a "global framework lock", and used whenever 2 threads 
-// of C code need access to global data.  This is different than the Python 
-// lock - this lock is used when no Python code can ever be called by the 
+// The second type of lock is a "global framework lock", and used whenever 2 threads
+// of C code need access to global data.  This is different than the Python
+// lock - this lock is used when no Python code can ever be called by the
 // threads, but the C code still needs thread-safety.
 
@@ -669,5 +691,5 @@
 //
 // This class magically waits for PyXPCOM framework global lock, and releases it
-// when finished.  
+// when finished.
 // NEVER new one of these objects - only use on the stack!
 class CEnterLeaveXPCOMFramework {
@@ -684,5 +706,5 @@
 //
 // This class magically waits for the Python global lock, and releases it
-// when finished.  
+// when finished.
 
 // Nested invocations will deadlock, so be careful.
@@ -749,5 +771,5 @@
 	// _before_ we release the lock, as some of
 	// the sys. attributes cleared (eg, the current exception)
-	// may need the lock to invoke their destructors - 
+	// may need the lock to invoke their destructors -
 	// specifically, when exc_value is a class instance, and
 	// the exception holds the last reference!
Index: trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp	(revision 39534)
+++ trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp	(revision 39535)
@@ -55,5 +55,5 @@
 #include "nspr.h" // PR_fprintf
 #ifdef VBOX
-#include "nsEventQueueUtils.h"
+# include "nsEventQueueUtils.h"
 #endif
 
@@ -319,4 +319,15 @@
 }
 
+#ifdef VBOX_DEBUG_LIFETIMES
+// @pymethod int|pythoncom|_DumpInterfaces|Dumps the interfaces still in existance to standard output
+static PyObject *
+PyXPCOMMethod_DumpInterfaces(PyObject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ":_DumpInterfaces"))
+		return NULL;
+	return PyInt_FromLong(_PyXPCOM_DumpInterfaces());
+}
+#endif
+
 // @pymethod int|pythoncom|_GetGatewayCount|Retrieves the number of gateway objects currently in existance
 static PyObject *
@@ -343,4 +354,8 @@
 	nr = NS_ShutdownXPCOM(nsnull);
 	Py_END_ALLOW_THREADS;
+
+#ifdef VBOX_DEBUG_LIFETIME
+	Py_nsISupports::dumpList();
+#endif
 
 	// Dont raise an exception - as we are probably shutting down
@@ -661,5 +676,9 @@
         {"DetachThread",  PyXPCOMMethod_DetachThread, 1},
 #endif
+#ifdef VBOX_DEBUG_LIFETIMES
+	{"_DumpInterfaces", PyXPCOMMethod_DumpInterfaces, 1},
+#endif
 	// These should no longer be used - just use the logging.getLogger('pyxpcom')...
+	/* bird: The above comment refers to LogWarning and LogError. Both now removed. */
 	{ NULL }
 };
