mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
Bug 1403348: Part 4 - Annotate certain startup crashes with AsyncShutdown script contents. r=mccr8 data-r=rweiss
We're seeing startup crashes which point to data corruption in the source of the AsyncShutdown component and module, but it's unclear whether the source of this corruption is on disk, in memory, or in XDR data. This change annotates crash reports with the contents of those files, so that we can compare the actual source with the corrupted values in the generated errors, and narrow down the source of the corruption. MozReview-Commit-ID: 7p8y73XUGLK --HG-- extra : rebase_source : 8e1b85df0cf69556af6f998f3d638bf2033e6ca0 extra : source : cf8613751378c8790b56131cd2a1be68573f9286
This commit is contained in:
parent
7d6982559e
commit
a036df8b65
@ -26,6 +26,7 @@
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozJSComponentLoader.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
@ -1134,6 +1135,7 @@ ServiceWorkerRegistrar::GetState(nsIPropertyBag**)
|
||||
|
||||
#define RELEASE_ASSERT_SUCCEEDED(rv, name) do { \
|
||||
if (NS_FAILED(rv)) { \
|
||||
mozJSComponentLoader::Get()->AnnotateCrashReport(); \
|
||||
if (rv == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS) { \
|
||||
if (auto* context = CycleCollectedJSContext::Get()) { \
|
||||
if (RefPtr<Exception> exn = context->GetPendingException()) { \
|
||||
|
@ -66,6 +66,10 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/js/xpconnect/loader',
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'test/mochitest.ini',
|
||||
]
|
||||
|
@ -69,6 +69,7 @@ LOCAL_INCLUDES += [
|
||||
'../system',
|
||||
'/dom/base',
|
||||
'/dom/bindings',
|
||||
'/js/xpconnect/loader',
|
||||
'/xpcom/build',
|
||||
'/xpcom/threads',
|
||||
]
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "mozilla/scache/StartupCacheUtils.h"
|
||||
#include "mozilla/MacroForEach.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/ScriptPreloader.h"
|
||||
#include "mozilla/dom/DOMPrefs.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
@ -56,6 +57,10 @@
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::scache;
|
||||
using namespace mozilla::loader;
|
||||
@ -359,6 +364,45 @@ ResolveModuleObjectProperty(JSContext* aCx, HandleObject aModObj, const char* na
|
||||
return aModObj;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
static mozilla::Result<nsCString, nsresult> ReadScript(ComponentLoaderInfo& aInfo);
|
||||
|
||||
static nsresult
|
||||
AnnotateScriptContents(const nsACString& aName, const nsACString& aURI)
|
||||
{
|
||||
ComponentLoaderInfo info(aURI);
|
||||
|
||||
nsCString str;
|
||||
MOZ_TRY_VAR(str, ReadScript(info));
|
||||
|
||||
// The crash reporter won't accept any strings with embedded nuls. We
|
||||
// shouldn't have any here, but if we do because of data corruption, we
|
||||
// still want the annotation. So replace any embedded nuls before
|
||||
// annotating.
|
||||
str.ReplaceSubstring(NS_LITERAL_CSTRING("\0"), NS_LITERAL_CSTRING("\\0"));
|
||||
|
||||
CrashReporter::AnnotateCrashReport(aName, str);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif // defined MOZ_CRASHREPORTER
|
||||
|
||||
nsresult
|
||||
mozJSComponentLoader::AnnotateCrashReport()
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
Unused << AnnotateScriptContents(
|
||||
NS_LITERAL_CSTRING("nsAsyncShutdownComponent"),
|
||||
NS_LITERAL_CSTRING("resource://gre/components/nsAsyncShutdown.js"));
|
||||
|
||||
Unused << AnnotateScriptContents(
|
||||
NS_LITERAL_CSTRING("AsyncShutdownModule"),
|
||||
NS_LITERAL_CSTRING("resource://gre/modules/AsyncShutdown.jsm"));
|
||||
#endif // defined MOZ_CRASHREPORTER
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const mozilla::Module*
|
||||
mozJSComponentLoader::LoadModule(FileLocation& aFile)
|
||||
{
|
||||
@ -401,6 +445,8 @@ mozJSComponentLoader::LoadModule(FileLocation& aFile)
|
||||
if (NS_FAILED(rv)) {
|
||||
// Temporary debugging assertion for bug 1403348:
|
||||
if (isCriticalModule && !exn.isUndefined()) {
|
||||
AnnotateCrashReport();
|
||||
|
||||
JSAutoCompartment ac(cx, xpc::PrivilegedJunkScope());
|
||||
JS_WrapValue(cx, &exn);
|
||||
|
||||
@ -705,6 +751,36 @@ mozJSComponentLoader::PrepareObjectForLocation(JSContext* aCx,
|
||||
return thisObj;
|
||||
}
|
||||
|
||||
static mozilla::Result<nsCString, nsresult>
|
||||
ReadScript(ComponentLoaderInfo& aInfo)
|
||||
{
|
||||
MOZ_TRY(aInfo.EnsureScriptChannel());
|
||||
|
||||
nsCOMPtr<nsIInputStream> scriptStream;
|
||||
MOZ_TRY(NS_MaybeOpenChannelUsingOpen2(aInfo.ScriptChannel(),
|
||||
getter_AddRefs(scriptStream)));
|
||||
|
||||
uint64_t len64;
|
||||
uint32_t bytesRead;
|
||||
|
||||
MOZ_TRY(scriptStream->Available(&len64));
|
||||
NS_ENSURE_TRUE(len64 < UINT32_MAX, Err(NS_ERROR_FILE_TOO_BIG));
|
||||
NS_ENSURE_TRUE(len64, Err(NS_ERROR_FAILURE));
|
||||
uint32_t len = (uint32_t)len64;
|
||||
|
||||
/* malloc an internal buf the size of the file */
|
||||
nsCString str;
|
||||
if (!str.SetLength(len, fallible))
|
||||
return Err(NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
/* read the file in one swoop */
|
||||
MOZ_TRY(scriptStream->Read(str.BeginWriting(), len, &bytesRead));
|
||||
if (bytesRead != len)
|
||||
return Err(NS_BASE_STREAM_OSERROR);
|
||||
|
||||
return Move(str);
|
||||
}
|
||||
|
||||
nsresult
|
||||
mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo& aInfo,
|
||||
nsIFile* aComponentFile,
|
||||
@ -795,39 +871,13 @@ mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo& aInfo,
|
||||
else
|
||||
Compile(cx, options, buf.get(), map.size(), &script);
|
||||
} else {
|
||||
rv = aInfo.EnsureScriptChannel();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIInputStream> scriptStream;
|
||||
rv = NS_MaybeOpenChannelUsingOpen2(aInfo.ScriptChannel(),
|
||||
getter_AddRefs(scriptStream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint64_t len64;
|
||||
uint32_t bytesRead;
|
||||
|
||||
rv = scriptStream->Available(&len64);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(len64 < UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
|
||||
if (!len64)
|
||||
return NS_ERROR_FAILURE;
|
||||
uint32_t len = (uint32_t)len64;
|
||||
|
||||
/* malloc an internal buf the size of the file */
|
||||
auto buf = MakeUniqueFallible<char[]>(len + 1);
|
||||
if (!buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
/* read the file in one swoop */
|
||||
rv = scriptStream->Read(buf.get(), len, &bytesRead);
|
||||
if (bytesRead != len)
|
||||
return NS_BASE_STREAM_OSERROR;
|
||||
|
||||
buf[len] = '\0';
|
||||
nsCString str;
|
||||
MOZ_TRY_VAR(str, ReadScript(aInfo));
|
||||
|
||||
if (reuseGlobal)
|
||||
CompileForNonSyntacticScope(cx, options, buf.get(), bytesRead, &script);
|
||||
CompileForNonSyntacticScope(cx, options, str.get(), str.Length(), &script);
|
||||
else
|
||||
Compile(cx, options, buf.get(), bytesRead, &script);
|
||||
Compile(cx, options, str.get(), str.Length(), &script);
|
||||
}
|
||||
// Propagate the exception, if one exists. Also, don't leave the stale
|
||||
// exception on this context.
|
||||
|
@ -78,6 +78,14 @@ class mozJSComponentLoader final : public mozilla::ModuleLoader,
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
/**
|
||||
* Temporary diagnostic function for startup crashes in bug 1403348:
|
||||
*
|
||||
* Annotate the crash report with the contents of the async shutdown
|
||||
* module/component scripts.
|
||||
*/
|
||||
nsresult AnnotateCrashReport();
|
||||
|
||||
protected:
|
||||
virtual ~mozJSComponentLoader();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user