Dump JS stack and information about the object for the assertion about using XPConnect on a scope with no Components in scope. (Bug 510489) r=mrbkap a2.0=DEBUG-only
authorL. David Baron <dbaron@dbaron.org>
Thu, 09 Dec 2010 20:38:52 -0800
changeset 59061 64a2a38349278afb0ab42ebb82cb4ac54a44f5b0
parent 59060 7cf0918f3bfa6f85e9b798654c8730dfc7a9129a
child 59062 e71b310f048498af352c9b22e18e9624288257ac
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersmrbkap
bugs510489
milestone2.0b8pre
Dump JS stack and information about the object for the assertion about using XPConnect on a scope with no Components in scope. (Bug 510489) r=mrbkap a2.0=DEBUG-only
js/src/xpconnect/src/xpcwrappednativescope.cpp
--- a/js/src/xpconnect/src/xpcwrappednativescope.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp
@@ -37,16 +37,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Class used to manage the wrapped native objects within a JS scope. */
 
 #include "xpcprivate.h"
 #include "XPCWrapper.h"
+#include "jsproxy.h"
 
 /***************************************************************************/
 
 #ifdef XPC_TRACK_SCOPE_STATS
 static int DEBUG_TotalScopeCount;
 static int DEBUG_TotalLiveScopeCount;
 static int DEBUG_TotalMaxScopeCount;
 static int DEBUG_TotalScopeTraversalCount;
@@ -751,16 +752,17 @@ GetScopeOfObject(JSObject* obj)
 
     // obj is one of our nsXPConnectWrappedNative objects.
     return ((XPCWrappedNative*)supports)->GetScope();
 }
 
 
 #ifdef DEBUG
 void DEBUG_CheckForComponentsInScope(JSContext* cx, JSObject* obj,
+                                     JSObject* startingObj,
                                      JSBool OKIfNotInitialized,
                                      XPCJSRuntime* runtime)
 {
     if(OKIfNotInitialized)
         return;
 
     if(!(JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS))
         return;
@@ -771,20 +773,35 @@ void DEBUG_CheckForComponentsInScope(JSC
         return;
 
     // This is pretty much always bad. It usually means that native code is
     // making a callback to an interface implemented in JavaScript, but the
     // document where the JS object was created has already been cleared and the
     // global properties of that document's window are *gone*. Generally this
     // indicates a problem that should be addressed in the design and use of the
     // callback code.
-    NS_ERROR("XPConnect is being called on a scope without a 'Components' property!");
+    NS_ERROR("XPConnect is being called on a scope without a 'Components' property!  (stack and details follow)");
+    printf("The current JS stack is:\n");
+    xpc_DumpJSStack(cx, JS_TRUE, JS_TRUE, JS_TRUE);
+
+    printf("And the object whose scope lacks a 'Components' property is:\n");
+    js_DumpObject(startingObj);
+
+    JSObject *p = startingObj;
+    while(p->isWrapper())
+    {
+        p = p->getProxyPrivate().toObjectOrNull();
+        if(!p)
+            break;
+        printf("which is a wrapper for:\n");
+        js_DumpObject(p);
+    }
 }
 #else
-#define DEBUG_CheckForComponentsInScope(ccx, obj, OKIfNotInitialized, runtime) \
+#define DEBUG_CheckForComponentsInScope(ccx, obj, startingObj, OKIfNotInitialized, runtime) \
     ((void)0)
 #endif
 
 // static
 XPCWrappedNativeScope*
 XPCWrappedNativeScope::FindInJSObjectScope(JSContext* cx, JSObject* obj,
                                            JSBool OKIfNotInitialized,
                                            XPCJSRuntime* runtime)
@@ -801,16 +818,20 @@ XPCWrappedNativeScope::FindInJSObjectSco
     if(scope)
         return scope;
 
     // Else we'll have to look up the parent chain to get the scope
 
     JSAutoEnterCompartment ac;
     ac.enterAndIgnoreErrors(cx, obj);
 
+#ifdef DEBUG
+    JSObject *startingObj = obj;
+#endif
+
     obj = JS_GetGlobalForObject(cx, obj);
 
     if(!runtime)
     {
         runtime = nsXPConnect::GetRuntimeInstance();
         NS_ASSERTION(runtime, "This should never be null!");
     }
 
@@ -829,17 +850,18 @@ XPCWrappedNativeScope::FindInJSObjectSco
                 found = cur;
                 break;
             }
         }
     }
 
     if(found) {
         // This cannot be called within the map lock!
-        DEBUG_CheckForComponentsInScope(cx, obj, OKIfNotInitialized, runtime);
+        DEBUG_CheckForComponentsInScope(cx, obj, startingObj,
+                                        OKIfNotInitialized, runtime);
         return found;
     }
 
     // Failure to find the scope is only OK if the caller told us it might fail.
     // This flag would only be set in the call from
     // XPCWrappedNativeScope::GetNewOrUsed
     NS_ASSERTION(OKIfNotInitialized, "No scope has this global object!");
     return nsnull;