From dbc9af380e37b1231fd2773b83669acaa7035511 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 8 Apr 2016 09:08:49 +1000 Subject: [PATCH] Bug 1262731 - Add JS_InitWithFailureDiagnostic(). r=sfink. This will help identify the cause of some Firefox start-up crashes when JS initialization fails. --HG-- extra : rebase_source : 3ed3c5e60f487e0ca11dc13bab93aa820ca8273f --- js/public/Initialization.h | 8 ++++++++ js/src/vm/DateTime.h | 2 +- js/src/vm/Initialization.cpp | 27 +++++++++++++++++---------- xpcom/build/XPCOMInit.cpp | 5 +++-- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/js/public/Initialization.h b/js/public/Initialization.h index fa022c9f60de..631441e48995 100644 --- a/js/public/Initialization.h +++ b/js/public/Initialization.h @@ -61,6 +61,14 @@ JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, extern JS_PUBLIC_API(bool) JS_Init(void); +/** + * A variant of JS_Init. On success it returns nullptr. On failure it returns a + * pointer to a string literal that describes how initialization failed, which + * can be useful for debugging purposes. + */ +extern JS_PUBLIC_API(const char*) +JS_InitWithFailureDiagnostic(void); + /** * Destroy free-standing resources allocated by SpiderMonkey, not associated * with any runtime, context, or other structure. diff --git a/js/src/vm/DateTime.h b/js/src/vm/DateTime.h index d9726fc554f0..3c3445bdc0f4 100644 --- a/js/src/vm/DateTime.h +++ b/js/src/vm/DateTime.h @@ -119,7 +119,7 @@ class DateTimeInfo } }; - friend bool ::JS_Init(); + friend const char* ::JS_InitWithFailureDiagnostic(); // Initialize global date/time tracking state. This operation occurs // during, and is restricted to, SpiderMonkey initialization. diff --git a/js/src/vm/Initialization.cpp b/js/src/vm/Initialization.cpp index e5108226621e..9086f35ddaee 100644 --- a/js/src/vm/Initialization.cpp +++ b/js/src/vm/Initialization.cpp @@ -59,8 +59,8 @@ CheckMessageParameterCounts() } #endif /* DEBUG */ -JS_PUBLIC_API(bool) -JS_Init(void) +JS_PUBLIC_API(const char*) +JS_InitWithFailureDiagnostic(void) { MOZ_ASSERT(libraryInitState == InitState::Uninitialized, "must call JS_Init once before any JSAPI operation except " @@ -76,18 +76,18 @@ JS_Init(void) using js::TlsPerThreadData; if (!TlsPerThreadData.init()) - return false; + return "JS_InitWithFailureDiagnostic: TlsPerThreadData.init() failed"; #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) if (!js::oom::InitThreadType()) - return false; + return "JS_InitWithFailureDiagnostic: js::oom::InitThreadType() failed"; js::oom::SetThreadType(js::oom::THREAD_TYPE_MAIN); #endif js::jit::ExecutableAllocator::initStatic(); if (!js::jit::InitializeIon()) - return false; + return "JS_InitWithFailureDiagnostic: js::jit::InitializeIon() failed"; js::DateTimeInfo::init(); @@ -95,20 +95,27 @@ JS_Init(void) UErrorCode err = U_ZERO_ERROR; u_init(&err); if (U_FAILURE(err)) - return false; + return "JS_InitWithFailureDiagnostic: u_init() failed"; #endif // EXPOSE_INTL_API if (!js::CreateHelperThreadsState()) - return false; + return "JS_InitWithFailureDiagnostic: js::CreateHelperThreadState() failed"; if (!FutexRuntime::initialize()) - return false; + return "JS_InitWithFailureDiagnostic: FutexRuntime::initialize() failed"; if (!js::gcstats::Statistics::initialize()) - return false; + return "JS_InitWithFailureDiagnostic: js::gcstats::Statistics::initialize() failed"; libraryInitState = InitState::Running; - return true; + return nullptr; +} + +JS_PUBLIC_API(bool) +JS_Init(void) +{ + const char* failure = JS_InitWithFailureDiagnostic(); + return !failure; } JS_PUBLIC_API(void) diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index e1d7a02e300f..3b3e47713199 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -704,8 +704,9 @@ NS_InitXPCOM2(nsIServiceManager** aResult, #endif // Initialize the JS engine. - if (!JS_Init()) { - NS_RUNTIMEABORT("JS_Init failed"); + const char* jsInitFailureReason = JS_InitWithFailureDiagnostic(); + if (jsInitFailureReason) { + NS_RUNTIMEABORT(jsInitFailureReason); } rv = nsComponentManagerImpl::gComponentManager->Init();