Bug 1403348: Add debugging assertions for more AsyncStartup failure modes. r?baku
Since we don't currently know where or how loading the service is failing, we
need logging in two places:
1) In ServiceWorkerRegistrar, which will tell us about any JS errors that
occur in the factory constructor.
2) In the XPConnect module loader, which will tell us about any JS errors
which happen while loading the top-level module script.
If the load fails due to a non-JS error, we'll simply get a nsresult failure
code, which well be less informative, but will still tell us something about
the failure mode.
MozReview-Commit-ID: 1CsDegJfiho
--- a/dom/workers/ServiceWorkerRegistrar.cpp
+++ b/dom/workers/ServiceWorkerRegistrar.cpp
@@ -1113,50 +1113,57 @@ ServiceWorkerRegistrar::GetName(nsAStrin
}
NS_IMETHODIMP
ServiceWorkerRegistrar::GetState(nsIPropertyBag**)
{
return NS_OK;
}
+#define RELEASE_ASSERT_SUCCEEDED(rv, name) do { \
+ if (NS_FAILED(rv)) { \
+ if (rv == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS) { \
+ if (auto* context = CycleCollectedJSContext::Get()) { \
+ if (nsCOMPtr<nsIException> exn = context->GetPendingException()) { \
+ nsAutoCString msg; \
+ if (NS_SUCCEEDED(exn->GetMessageMoz(msg))) { \
+ MOZ_CRASH_UNSAFE_PRINTF("Failed to get " name ": %s", msg.get());\
+ } \
+ } \
+ } \
+ } \
+ \
+ nsAutoCString errorName; \
+ GetErrorName(rv, errorName); \
+ MOZ_CRASH_UNSAFE_PRINTF("Failed to get " name ": %s", \
+ errorName.get()); \
+ } \
+ } while (0)
+
+
nsCOMPtr<nsIAsyncShutdownClient>
ServiceWorkerRegistrar::GetShutdownPhase() const
{
- nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
- MOZ_RELEASE_ASSERT(svc);
-
- nsCOMPtr<nsIAsyncShutdownClient> client;
- nsresult rv = svc->GetProfileBeforeChange(getter_AddRefs(client));
+ nsresult rv;
+ nsCOMPtr<nsIAsyncShutdownService> svc = do_GetService(
+ "@mozilla.org/async-shutdown-service;1", &rv);
// If this fails, something is very wrong on the JS side (or we're out of
// memory), and there's no point in continuing startup. Include as much
// information as possible in the crash report.
- if (NS_FAILED(rv)) {
- if (rv == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS) {
- if (auto* context = CycleCollectedJSContext::Get()) {
- if (nsCOMPtr<nsIException> exn = context->GetPendingException()) {
- nsAutoCString msg;
- if (NS_SUCCEEDED(exn->GetMessageMoz(msg))) {
- MOZ_CRASH_UNSAFE_PRINTF("Failed to get profileBeforeChange shutdown blocker: %s",
- msg.get());
+ RELEASE_ASSERT_SUCCEEDED(rv, "async shutdown service");
+
- }
- }
- }
- }
-
- nsAutoCString errorName;
- GetErrorName(rv, errorName);
- MOZ_CRASH_UNSAFE_PRINTF("Failed to get profileBeforeChange shutdown blocker: %s",
- errorName.get());
- }
- MOZ_RELEASE_ASSERT(client);
+ nsCOMPtr<nsIAsyncShutdownClient> client;
+ rv = svc->GetProfileBeforeChange(getter_AddRefs(client));
+ RELEASE_ASSERT_SUCCEEDED(rv, "profileBeforeChange shutdown blocker");
return Move(client);
}
+#undef RELEASE_ASSERT_SUCCEEDED
+
void
ServiceWorkerRegistrar::Shutdown()
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(!mShuttingDown);
mShuttingDown = true;
MaybeScheduleShutdownCompleted();
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -31,16 +31,17 @@
#include "nsIJARURI.h"
#include "nsNetUtil.h"
#include "jsprf.h"
#include "nsJSPrincipals.h"
#include "nsJSUtils.h"
#include "xpcprivate.h"
#include "xpcpublic.h"
#include "nsContentUtils.h"
+#include "nsReadableUtils.h"
#include "nsXULAppAPI.h"
#include "GeckoProfiler.h"
#include "WrapperFactory.h"
#include "AutoMemMap.h"
#include "ScriptPreloader-inl.h"
#include "mozilla/AddonPathService.h"
@@ -383,21 +384,39 @@ mozJSComponentLoader::LoadModule(FileLoc
ModuleEntry* mod;
if (mModules.Get(spec, &mod))
return mod;
dom::AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
+ bool isCriticalModule = StringEndsWith(spec, NS_LITERAL_CSTRING("/nsAsyncShutdown.js"));
+
nsAutoPtr<ModuleEntry> entry(new ModuleEntry(RootingContext::get(cx)));
- RootedValue dummy(cx);
+ RootedValue exn(cx);
rv = ObjectForLocation(info, file, &entry->obj, &entry->thisObjectKey,
- &entry->location, false, &dummy);
+ &entry->location, isCriticalModule, &exn);
if (NS_FAILED(rv)) {
+ // Temporary debugging assertion for bug 1403348:
+ if (isCriticalModule && !exn.isUndefined()) {
+ JSAutoCompartment ac(cx, xpc::PrivilegedJunkScope());
+ JS_WrapValue(cx, &exn);
+
+ nsAutoCString file;
+ uint32_t line;
+ uint32_t column;
+ nsAutoString msg;
+ nsContentUtils::ExtractErrorValues(cx, exn, file, &line, &column, msg);
+
+ NS_ConvertUTF16toUTF8 cMsg(msg);
+ MOZ_CRASH_UNSAFE_PRINTF("Failed to load module \"%s\": "
+ "[\"%s\" {file: \"%s\", line: %u}]",
+ spec.get(), cMsg.get(), file.get(), line);
+ }
return nullptr;
}
nsCOMPtr<nsIComponentManager> cm;
rv = NS_GetComponentManager(getter_AddRefs(cm));
if (NS_FAILED(rv))
return nullptr;