From: timeless@mozdev.org Bug 480851 ASSERTION: "You can't dereference a NULL nsCOMPtr with operator->()" with Firebug installed [@ DEBUG_CheckWrapperThreadSafety] diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -51,18 +51,21 @@ #include "jsfun.h" #include "jsscript.h" #include "nsThreadUtilsInternal.h" +#include "nsIObserverService.h" #include "dom_quickstubs.h" -NS_IMPL_THREADSAFE_ISUPPORTS6(nsXPConnect, +NS_IMPL_THREADSAFE_ISUPPORTS7(nsXPConnect, nsIXPConnect, nsISupportsWeakReference, nsIThreadObserver, nsIJSRuntimeService, nsIJSContextStack, - nsIThreadJSContextStack) + nsIThreadJSContextStack, + nsIObserver) nsXPConnect* nsXPConnect::gSelf = nsnull; JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE; +JSBool nsXPConnect::gThreadsGone = JS_FALSE; PRUint32 nsXPConnect::gReportAllJSExceptions = 0; // Global cache of the default script security manager (QI'd to @@ -122,6 +125,13 @@ nsXPConnect::nsXPConnect() char* reportableEnv = PR_GetEnv("MOZ_REPORT_ALL_JS_EXCEPTIONS"); if(reportableEnv && *reportableEnv) gReportAllJSExceptions = 1; + + { + nsCOMPtr os(do_GetService("@mozilla.org/observer-service;1")); + if (os) { + os->AddObserver(this, "xpcom-shutdown-threads", PR_TRUE); + } + } } nsXPConnect::~nsXPConnect() @@ -2641,6 +2651,22 @@ nsXPConnect::SetSafeJSContext(JSContext return data->GetJSContextStack()->SetSafeJSContext(aSafeJSContext); } +/* void observe(); */ +NS_IMETHODIMP +nsXPConnect::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData) +{ + if (!aTopic) + return NS_OK; + + nsDependentCString topic(aTopic); + if (topic.EqualsLiteral("xpcom-shutdown-threads")) { + gThreadsGone = JS_TRUE; + return NS_OK; + } + + return NS_OK; +} + nsIPrincipal* nsXPConnect::GetPrincipal(JSObject* obj, PRBool allowShortCircuit) const { diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -104,6 +104,7 @@ #include "nsIConsoleService.h" #include "nsIScriptError.h" #include "nsIExceptionService.h" +#include "nsIObserver.h" #include "nsVariant.h" #include "nsIPropertyBag.h" @@ -457,7 +458,8 @@ class nsXPConnect : public nsIXPConnect, public nsCycleCollectionJSRuntime, public nsCycleCollectionParticipant, public nsIJSRuntimeService, - public nsIThreadJSContextStack + public nsIThreadJSContextStack, + public nsIObserver { public: // all the interface method declarations... @@ -467,6 +469,7 @@ public: NS_DECL_NSIJSRUNTIMESERVICE NS_DECL_NSIJSCONTEXTSTACK NS_DECL_NSITHREADJSCONTEXTSTACK + NS_DECL_NSIOBSERVER // non-interface implementation public: @@ -564,6 +567,7 @@ private: // Singleton instance static nsXPConnect* gSelf; static JSBool gOnceAliveNowDead; + static JSBool gThreadsGone; XPCJSRuntime* mRuntime; nsCOMPtr mInterfaceInfoManager; diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp --- a/js/src/xpconnect/src/xpcwrappednative.cpp +++ b/js/src/xpconnect/src/xpcwrappednative.cpp @@ -3687,6 +3687,9 @@ void DEBUG_ReportWrapperThreadSafetyErro void DEBUG_CheckWrapperThreadSafety(const XPCWrappedNative* wrapper) { + if(nsXPConnect::gThreadsGone) + return; + XPCWrappedNativeProto* proto = wrapper->GetProto(); if(proto && proto->ClassIsThreadSafe()) return;