author | Noemi Erli <nerli@mozilla.com> |
Sat, 04 Aug 2018 12:39:40 +0300 | |
changeset 430136 | 4146a5857135b8542858b9e23bc5a71237e05f49 |
parent 430135 | 48904c06f28c87a579f8f2c42b931982af353655 |
child 430161 | 76b09340b737a4babc322ef57de548ed1dee1407 |
child 430166 | c5feed1e4a18a5ef594c9385927795109b750abf |
push id | 34383 |
push user | nerli@mozilla.com |
push date | Sat, 04 Aug 2018 12:28:43 +0000 |
treeherder | mozilla-central@4146a5857135 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1348273, 1123480 |
milestone | 63.0a1 |
backs out | 1e9ecba54e7b1e6ee614e323ece9c98c373311a9 |
first release with | nightly linux32
4146a5857135
/
63.0a1
/
20180804124335
/
files
nightly linux64
4146a5857135
/
63.0a1
/
20180804124335
/
files
nightly mac
4146a5857135
/
63.0a1
/
20180804124335
/
files
nightly win32
4146a5857135
/
63.0a1
/
20180804124335
/
files
nightly win64
4146a5857135
/
63.0a1
/
20180804124335
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
63.0a1
/
20180804124335
/
pushlog to previous
nightly linux64
63.0a1
/
20180804124335
/
pushlog to previous
nightly mac
63.0a1
/
20180804124335
/
pushlog to previous
nightly win32
63.0a1
/
20180804124335
/
pushlog to previous
nightly win64
63.0a1
/
20180804124335
/
pushlog to previous
|
--- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -1388,17 +1388,17 @@ nsAccessibilityService::Init() gApplicationAccessible = new ApplicationAccessible(); #endif // defined(XP_WIN) } NS_ADDREF(gApplicationAccessible); // will release in Shutdown() gApplicationAccessible->Init(); CrashReporter:: - AnnotateCrashReport(CrashReporter::Annotation::Accessibility, + AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"), NS_LITERAL_CSTRING("Active")); #ifdef XP_WIN sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >; sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >; #endif // Now its safe to start platform accessibility.
--- a/accessible/windows/msaa/Compatibility.cpp +++ b/accessible/windows/msaa/Compatibility.cpp @@ -237,17 +237,17 @@ Compatibility::HasKnownNonUiaConsumer() void Compatibility::Init() { // Note we collect some AT statistics/telemetry here for convenience. InitConsumers(); CrashReporter:: - AnnotateCrashReport(CrashReporter::Annotation::AccessibilityInProcClient, + AnnotateCrashReport(NS_LITERAL_CSTRING("AccessibilityInProcClient"), nsPrintfCString("0x%X", sConsumers)); // Gather telemetry uint32_t temp = sConsumers; for (int i = 0; temp; i++) { if (temp & 0x1) statistics::A11yConsumers(i); @@ -431,19 +431,18 @@ UseIAccessibleProxyStub() // Otherwise we try the proxy/stub if (IsIAccessiblePSRegistered()) { return true; } // If we reach this point then something is seriously wrong with the // IAccessible configuration in the computer's registry. Let's annotate this // so that we can easily determine this condition during crash analysis. - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IAccessibleConfig, - NS_LITERAL_CSTRING("NoSystemTypeLibOrPS")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IAccessibleConfig"), + NS_LITERAL_CSTRING("NoSystemTypeLibOrPS")); return false; } #endif // !defined(HAVE_64BIT_BUILD) uint16_t Compatibility::GetActCtxResourceId() {
--- a/accessible/windows/msaa/LazyInstantiator.cpp +++ b/accessible/windows/msaa/LazyInstantiator.cpp @@ -12,16 +12,17 @@ #include "mozilla/a11y/Platform.h" #include "mozilla/Assertions.h" #include "mozilla/mscom/MainThreadRuntime.h" #include "mozilla/mscom/Registration.h" #include "mozilla/UniquePtr.h" #include "nsAccessibilityService.h" #include "nsWindowsHelpers.h" #include "nsCOMPtr.h" +#include "nsExceptionHandler.h" #include "nsIFile.h" #include "nsXPCOM.h" #include "RootAccessibleWrap.h" #include "WinUtils.h" #include <oaidl.h> #if !defined(STATE_SYSTEM_NORMAL)
--- a/accessible/windows/msaa/Platform.cpp +++ b/accessible/windows/msaa/Platform.cpp @@ -353,17 +353,17 @@ AccumulateInstantiatorTelemetry(const ns if (!aValue.IsEmpty()) { #if defined(MOZ_TELEMETRY_REPORTING) Telemetry::ScalarSet(Telemetry::ScalarID::A11Y_INSTANTIATORS, aValue); #endif // defined(MOZ_TELEMETRY_REPORTING) #if defined(MOZ_CRASHREPORTER) CrashReporter:: - AnnotateCrashReport(CrashReporter::Annotation::AccessibilityClient, + AnnotateCrashReport(NS_LITERAL_CSTRING("AccessibilityClient"), NS_ConvertUTF16toUTF8(aValue)); #endif // defined(MOZ_CRASHREPORTER) } } static void GatherInstantiatorTelemetry(nsIFile* aClientExe) {
--- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -1,20 +1,16 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ChromeUtils.defineModuleGetter(this, "Blocklist", "resource://gre/modules/Blocklist.jsm"); -XPCOMUtils.defineLazyModuleGetters(this, { - PluginCrashReporter: "resource:///modules/ContentCrashHandlers.jsm", -}); - var gPluginHandler = { PREF_SESSION_PERSIST_MINUTES: "plugin.sessionPermissionNow.intervalInMinutes", PREF_PERSISTENT_DAYS: "plugin.persistentPermissionAlways.intervalInDays", PREF_SHOW_INFOBAR: "plugins.show_infobar", PREF_INFOBAR_DISMISSAL_PERMANENT: "plugins.remember_infobar_dismissal", MESSAGES: [ "PluginContent:ShowClickToPlayNotification", @@ -581,17 +577,17 @@ var gPluginHandler = { let runID = propertyBag.getPropertyAsUint32("runID"); let uglyPluginName = propertyBag.getPropertyAsAString("pluginName"); let pluginName = BrowserUtils.makeNicePluginName(uglyPluginName); let pluginDumpID = propertyBag.getPropertyAsAString("pluginDumpID"); // If we don't have a minidumpID, we can't (or didn't) submit anything. // This can happen if the plugin is killed from the task manager. let state; - if (!AppConstants.MOZ_CRASHREPORTER || !CrashReporter.enabled) { + if (!AppConstants.MOZ_CRASHREPORTER || !gCrashReporter.enabled) { // This state tells the user that crash reporting is disabled, so we // cannot send a report. state = "noSubmit"; } else if (!pluginDumpID) { // This state tells the user that there is no crash report available. state = "noReport"; } else { // This state asks the user to submit a crash report.
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -18,17 +18,16 @@ const {WebExtensionPolicy} = Cu.getGloba XPCOMUtils.defineLazyModuleGetters(this, { BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm", BrowserUtils: "resource://gre/modules/BrowserUtils.jsm", BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm", CharsetMenu: "resource://gre/modules/CharsetMenu.jsm", Color: "resource://gre/modules/Color.jsm", ContentSearch: "resource:///modules/ContentSearch.jsm", ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm", - CrashReporter: "resource://gre/modules/CrashReporter.jsm", CustomizableUI: "resource:///modules/CustomizableUI.jsm", Deprecated: "resource://gre/modules/Deprecated.jsm", DownloadsCommon: "resource:///modules/DownloadsCommon.jsm", E10SUtils: "resource://gre/modules/E10SUtils.jsm", ExtensionsUI: "resource:///modules/ExtensionsUI.jsm", FormValidationHandler: "resource:///modules/FormValidationHandler.jsm", LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm", HomePage: "resource:///modules/HomePage.jsm", @@ -68,16 +67,21 @@ XPCOMUtils.defineLazyModuleGetters(this, Utils: "resource://gre/modules/sessionstore/Utils.jsm", Weave: "resource://services-sync/main.js", WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm", fxAccounts: "resource://gre/modules/FxAccounts.jsm", webrtcUI: "resource:///modules/webrtcUI.jsm", ZoomUI: "resource:///modules/ZoomUI.jsm", }); +if (AppConstants.MOZ_CRASHREPORTER) { + ChromeUtils.defineModuleGetter(this, "PluginCrashReporter", + "resource:///modules/ContentCrashHandlers.jsm"); +} + XPCOMUtils.defineLazyScriptGetter(this, "PlacesTreeView", "chrome://browser/content/places/treeView.js"); XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesController", "PlacesControllerDragHelper"], "chrome://browser/content/places/controller.js"); XPCOMUtils.defineLazyScriptGetter(this, "PrintUtils", "chrome://global/content/printUtils.js"); XPCOMUtils.defineLazyScriptGetter(this, "ZoomManager", @@ -136,16 +140,22 @@ XPCOMUtils.defineLazyServiceGetters(this gAboutNewTabService: ["@mozilla.org/browser/aboutnewtab-service;1", "nsIAboutNewTabService"], gDNSService: ["@mozilla.org/network/dns-service;1", "nsIDNSService"], gSerializationHelper: ["@mozilla.org/network/serialization-helper;1", "nsISerializationHelper"], Marionette: ["@mozilla.org/remote/marionette;1", "nsIMarionette"], SessionStartup: ["@mozilla.org/browser/sessionstartup;1", "nsISessionStartup"], WindowsUIUtils: ["@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils"], }); +if (AppConstants.MOZ_CRASHREPORTER) { + XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter", + "@mozilla.org/xre/app-info;1", + "nsICrashReporter"); +} + XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() { return Services.strings.createBundle("chrome://browser/locale/browser.properties"); }); XPCOMUtils.defineLazyGetter(this, "gNavigatorBundle", function() { // This is a stringbundle-like interface to gBrowserBundle, formerly a getter for // the "bundle_browser" element. return { getString(key) { @@ -4801,17 +4811,17 @@ var XULBrowserWindow = { try { // If the current URI contains a username/password, remove it. uri = aLocationURI.mutate() .setUserPass("") .finalize(); } catch (ex) { /* Ignore failures on about: URIs. */ } try { - CrashReporter.addAnnotation(CrashReporter.annotations.URL, uri.spec); + gCrashReporter.annotateCrashReport("URL", uri.spec); } catch (ex) { // Don't make noise when the crash reporter is built but not enabled. if (ex.result != Cr.NS_ERROR_NOT_INITIALIZED) { throw ex; } } } },
--- a/browser/base/content/test/performance/browser_startup_content.js +++ b/browser/base/content/test/performance/browser_startup_content.js @@ -23,17 +23,16 @@ const whitelist = { "extension-process-script.js", ]), modules: new Set([ "chrome://mochikit/content/ShutdownLeaksCollector.jsm", // General utilities "resource://gre/modules/AppConstants.jsm", "resource://gre/modules/AsyncShutdown.jsm", - "resource://gre/modules/CrashReporter.jsm", "resource://gre/modules/DeferredTask.jsm", "resource://gre/modules/PromiseUtils.jsm", "resource://gre/modules/Services.jsm", // bug 1464542 "resource://gre/modules/Timer.jsm", "resource://gre/modules/XPCOMUtils.jsm", // Logging related "resource://gre/modules/Log.jsm",
--- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1697,18 +1697,18 @@ nsDocShell::GetUseRemoteTabs(bool* aUseR *aUseRemoteTabs = mUseRemoteTabs; return NS_OK; } NS_IMETHODIMP nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) { if (aUseRemoteTabs) { - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled, - true); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("DOMIPCEnabled"), + NS_LITERAL_CSTRING("1")); } mUseRemoteTabs = aUseRemoteTabs; return NS_OK; } NS_IMETHODIMP nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime)
--- a/dom/events/TouchEvent.cpp +++ b/dom/events/TouchEvent.cpp @@ -271,18 +271,20 @@ TouchEvent::PrefEnabled(nsIDocShell* aDo } else { if (sPrefCacheValue == 2) { enabled = PlatformSupportsTouch(); static bool firstTime = true; // The touch screen data seems to be inaccurate in the parent process, // and we really need the crash annotation in child processes. if (firstTime && !XRE_IsParentProcess()) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::HasDeviceTouchScreen, enabled); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("HasDeviceTouchScreen"), + enabled ? + NS_LITERAL_CSTRING("1") : + NS_LITERAL_CSTRING("0")); firstTime = false; } #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) if (enabled && aDocShell) { // APZ might be disabled on this particular widget, in which case // TouchEvent support will also be disabled. Try to detect that. RefPtr<nsPresContext> pc;
--- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -1766,23 +1766,26 @@ ContentChild::RecvSetProcessSandbox(cons } #elif defined(XP_WIN) mozilla::SandboxTarget::Instance()->StartSandbox(); #elif defined(XP_MACOSX) sandboxEnabled = StartMacOSContentSandbox(); #endif CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ContentSandboxEnabled, sandboxEnabled); + NS_LITERAL_CSTRING("ContentSandboxEnabled"), + sandboxEnabled? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0")); #if defined(XP_LINUX) && !defined(OS_ANDROID) + nsAutoCString flagsString; + flagsString.AppendInt(SandboxInfo::Get().AsInteger()); + CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ContentSandboxCapabilities, - static_cast<int>(SandboxInfo::Get().AsInteger())); + NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString); #endif /* XP_LINUX && !OS_ANDROID */ - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RemoteType, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("RemoteType"), NS_ConvertUTF16toUTF8(GetRemoteType())); #endif /* MOZ_CONTENT_SANDBOX */ return IPC_OK(); } mozilla::ipc::IPCResult ContentChild::RecvBidiKeyboardNotify(const bool& aIsLangRTL, @@ -2434,18 +2437,17 @@ ContentChild::ProcessingError(Result aCo case MsgValueError: break; default: MOZ_CRASH("not reached"); } nsDependentCString reason(aReason); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ipc_channel_error, reason); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ipc_channel_error"), reason); MOZ_CRASH("Content child abort due to IPC error"); } nsresult ContentChild::AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver) { @@ -3110,19 +3112,18 @@ ContentChild::RecvShutdown() void ContentChild::ShutdownInternal() { // If we receive the shutdown message from within a nested event loop, we want // to wait for that event loop to finish. Otherwise we could prematurely // terminate an "unload" or "pagehide" event handler (which might be doing a // sync XHR, for example). - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCShutdownState, - NS_LITERAL_CSTRING("RecvShutdown")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"), + NS_LITERAL_CSTRING("RecvShutdown")); MOZ_ASSERT(NS_IsMainThread()); RefPtr<nsThread> mainThread = nsThreadManager::get().GetCurrentThread(); // Note that we only have to check the recursion count for the current // cooperative thread. Since the Shutdown message is not labeled with a // SchedulerGroup, there can be no other cooperative threads doing work while // we're running. if (mainThread && mainThread->RecursionDepth() > 1) { @@ -3170,21 +3171,20 @@ ContentChild::ShutdownInternal() } #endif // Start a timer that will insure we quickly exit after a reasonable // period of time. Prevents shutdown hangs after our connection to the // parent closes. StartForceKillTimer(); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCShutdownState, - NS_LITERAL_CSTRING("SendFinishShutdown (sending)")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"), + NS_LITERAL_CSTRING("SendFinishShutdown (sending)")); bool sent = SendFinishShutdown(); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IPCShutdownState, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"), sent ? NS_LITERAL_CSTRING("SendFinishShutdown (sent)") : NS_LITERAL_CSTRING("SendFinishShutdown (failed)")); } PBrowserOrId ContentChild::GetBrowserOrId(TabChild* aTabChild) { if (!aTabChild ||
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -3365,21 +3365,23 @@ ContentParent::KillHard(const char* aRea // of the parent and child for submission to the crash server. if (mCrashReporter) { // GeneratePairedMinidump creates two minidumps for us - the main // one is for the content process we're about to kill, and the other // one is for the main browser process. That second one is the extra // minidump tagging along, so we have to tell the crash reporter that // it exists and is being appended. nsAutoCString additionalDumps("browser"); - mCrashReporter->AddAnnotation( - CrashReporter::Annotation::additional_minidumps, additionalDumps); + mCrashReporter->AddNote( + NS_LITERAL_CSTRING("additional_minidumps"), + additionalDumps); nsDependentCString reason(aReason); - mCrashReporter->AddAnnotation(CrashReporter::Annotation::ipc_channel_error, - reason); + mCrashReporter->AddNote( + NS_LITERAL_CSTRING("ipc_channel_error"), + reason); Telemetry::Accumulate(Telemetry::SUBPROCESS_KILL_HARD, reason, 1); RefPtr<ContentParent> self = this; std::function<void(bool)> callback = [self](bool aResult) { self->OnGenerateMinidumpComplete(aResult); }; // Generate the report and insert into the queue for submittal.
--- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1168,17 +1168,17 @@ TabChild::RecvLoadURL(const nsCString& a WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI).get(), nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL, nullptr, nullptr, nullptr, nsContentUtils::GetSystemPrincipal()); if (NS_FAILED(rv)) { NS_WARNING("WebNavigation()->LoadURI failed. Eating exception, what else can I do?"); } - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aURI); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("URL"), aURI); return IPC_OK(); } void TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier, const layers::LayersId& aLayersId, const CompositorOptions& aCompositorOptions,
--- a/dom/media/gmp/GMPChild.cpp +++ b/dom/media/gmp/GMPChild.cpp @@ -555,19 +555,18 @@ ToCString(const nsTArray<Pair<nsCString, mozilla::ipc::IPCResult GMPChild::AnswerStartPlugin(const nsString& aAdapter) { LOGD("%s", __FUNCTION__); nsCString libPath; if (!GetUTF8LibPath(libPath)) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GMPLibraryPath, - NS_ConvertUTF16toUTF8(mPluginPath)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GMPLibraryPath"), + NS_ConvertUTF16toUTF8(mPluginPath)); #ifdef XP_WIN return IPC_FAIL( this, nsPrintfCString("Failed to get lib path with error(%d).", GetLastError()) .get()); #else return IPC_FAIL( @@ -611,19 +610,18 @@ GMPChild::AnswerStartPlugin(const nsStri } if (!mGMPLoader->Load(libPath.get(), libPath.Length(), platformAPI, adapter)) { NS_WARNING("Failed to load GMP"); delete platformAPI; - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GMPLibraryPath, - NS_ConvertUTF16toUTF8(mPluginPath)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GMPLibraryPath"), + NS_ConvertUTF16toUTF8(mPluginPath)); #ifdef XP_WIN return IPC_FAIL( this, nsPrintfCString("Failed to load GMP with error(%d).", GetLastError()) .get()); #else return IPC_FAIL(
--- a/dom/media/gmp/GMPParent.cpp +++ b/dom/media/gmp/GMPParent.cpp @@ -458,23 +458,20 @@ GMPParent::EnsureProcessLoaded() nsresult rv = LoadProcess(); return NS_SUCCEEDED(rv); } void GMPParent::WriteExtraDataForMinidump() { - mCrashReporter->AddAnnotation(CrashReporter::Annotation::GMPPlugin, true); - mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename, - NS_ConvertUTF16toUTF8(mName)); - mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName, - mDisplayName); - mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion, - mVersion); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("GMPPlugin"), NS_LITERAL_CSTRING("1")); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginFilename"), NS_ConvertUTF16toUTF8(mName)); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginName"), mDisplayName); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginVersion"), mVersion); } bool GMPParent::GetCrashID(nsString& aResult) { if (!mCrashReporter) { return false; }
--- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -6,16 +6,17 @@ /* nsPluginHost.cpp - top-level plugin management code */ #include "nscore.h" #include "nsPluginHost.h" #include <cstdlib> #include <stdio.h> #include "prio.h" +#include "nsExceptionHandler.h" #include "nsNPAPIPlugin.h" #include "nsNPAPIPluginStreamListener.h" #include "nsNPAPIPluginInstance.h" #include "nsPluginInstanceOwner.h" #include "nsObjectLoadingContent.h" #include "nsIHTTPHeaderListener.h" #include "nsIHttpHeaderVisitor.h" #include "nsIObserverService.h"
--- a/dom/plugins/base/nsPluginsDirDarwin.cpp +++ b/dom/plugins/base/nsPluginsDirDarwin.cpp @@ -405,24 +405,53 @@ nsresult nsPluginFile::GetPluginInfo(nsP // First look for data in a bundle plist if (bundle) { ParsePlistPluginInfo(info, bundle); ::CFRelease(bundle); if (info.fVariantCount > 0) return NS_OK; } + // Don't load "fbplugin" or any plugins whose name starts with "fbplugin_" + // (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later. + // A "fbplugin" file crashes on load, in the call to LoadPlugin() below. + // See bug 1086977. + if (nsCocoaFeatures::OnYosemiteOrLater()) { + if (fileName.EqualsLiteral("fbplugin") || + StringBeginsWith(fileName, NS_LITERAL_CSTRING("fbplugin_"))) { + nsAutoCString msg; + msg.AppendPrintf("Preventing load of %s (see bug 1086977)", + fileName.get()); + NS_WARNING(msg.get()); + return NS_ERROR_FAILURE; + } + + // The block above assumes that "fbplugin" is the filename of the plugin + // to be blocked, or that the filename starts with "fbplugin_". But we + // don't yet know for sure if this is always true. So for the time being + // record extra information in our crash logs. + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"), + fileName); + } + // It's possible that our plugin has 2 entry points that'll give us mime type // info. Quicktime does this to get around the need of having admin rights to // change mime info in the resource fork. We need to use this info instead of // the resource. See bug 113464. // Sadly we have to load the library for this to work. rv = LoadPlugin(outLibrary); + if (nsCocoaFeatures::OnYosemiteOrLater()) { + // If we didn't crash in LoadPlugin(), change the previous annotation so we + // don't sow confusion. + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"), + NS_LITERAL_CSTRING("Didn't crash, please ignore")); + } + if (NS_FAILED(rv)) return rv; // Try to get data from NP_GetMIMEDescription if (pLibrary) { NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME); if (pfnGetMimeDesc) ParsePluginMimeDescription(pfnGetMimeDesc(), info);
--- a/dom/plugins/ipc/PluginMessageUtils.h +++ b/dom/plugins/ipc/PluginMessageUtils.h @@ -18,16 +18,17 @@ #include "gfxipc/ShadowLayerUtils.h" #include "npapi.h" #include "npruntime.h" #include "npfunctions.h" #include "nsString.h" #include "nsTArray.h" #include "mozilla/Logging.h" +#include "nsExceptionHandler.h" #include "nsHashKeys.h" #ifdef XP_MACOSX #include "PluginInterposeOSX.h" #else namespace mac_plugin_interposing { class NSCursorInfo { }; } #endif using mac_plugin_interposing::NSCursorInfo;
--- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -733,46 +733,36 @@ PluginModuleChromeParent::WriteExtraData // Get the plugin filename, try to get just the file leafname const std::string& pluginFile = mSubprocess->GetPluginFilePath(); size_t filePos = pluginFile.rfind(FILE_PATH_SEPARATOR); if (filePos == std::string::npos) filePos = 0; else filePos++; - mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename, - cstring(pluginFile.substr(filePos).c_str())); - mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName, - mPluginName); - mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion, - mPluginVersion); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginFilename"), cstring(pluginFile.substr(filePos).c_str())); + + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginName"), mPluginName); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginVersion"), mPluginVersion); if (mCrashReporter) { #ifdef XP_WIN if (mPluginCpuUsageOnHang.Length() > 0) { - mCrashReporter->AddAnnotation( - CrashReporter::Annotation::NumberOfProcessors, - PR_GetNumberOfProcessors()); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("NumberOfProcessors"), + nsPrintfCString("%d", PR_GetNumberOfProcessors())); nsCString cpuUsageStr; cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100); - mCrashReporter->AddAnnotation( - CrashReporter::Annotation::PluginCpuUsage, - cpuUsageStr); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginCpuUsage"), cpuUsageStr); #ifdef MOZ_CRASHREPORTER_INJECTOR - for (uint32_t i = 1; i < mPluginCpuUsageOnHang.Length(); ++i) { + for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) { nsCString tempStr; tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100); - // HACK: There can only be at most two flash processes hence - // the hardcoded annotations - CrashReporter::Annotation annotation = - (i == 1) ? CrashReporter::Annotation::CpuUsageFlashProcess1 - : CrashReporter::Annotation::CpuUsageFlashProcess2; - mCrashReporter->AddAnnotation(annotation, tempStr); + mCrashReporter->AddNote(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr); } #endif } #endif } } void @@ -1249,18 +1239,18 @@ PluginModuleChromeParent::OnTakeFullMini // Include the content process minidump if (CreatePluginMinidump(aContentPid, 0, pluginDumpFile, NS_LITERAL_CSTRING("content"))) { additionalDumps.AppendLiteral(",content"); } } } - mCrashReporter->AddAnnotation(Annotation::additional_minidumps, - additionalDumps); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("additional_minidumps"), + additionalDumps); mTakeFullMinidumpCallback.Invoke(mCrashReporter->MinidumpID()); } else { mTakeFullMinidumpCallback.Invoke(EmptyString()); NS_WARNING("failed to capture paired minidumps from hang"); } } @@ -1311,25 +1301,28 @@ PluginModuleChromeParent::TerminateChild mCrashReporterMutex.AssertCurrentThreadIn(); if (!mCrashReporter) { // If mCrashReporter is null then the hang has ended, the plugin module // is shutting down. There's nothing to do here. mTerminateChildProcessCallback.Invoke(true); return; } - mCrashReporter->AddAnnotation(Annotation::PluginHang, true); - mCrashReporter->AddAnnotation(Annotation::HangMonitorDescription, - aMonitorDescription); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginHang"), + NS_LITERAL_CSTRING("1")); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("HangMonitorDescription"), + aMonitorDescription); #ifdef XP_WIN if (mHangUIParent) { unsigned int hangUIDuration = mHangUIParent->LastShowDurationMs(); if (hangUIDuration) { - mCrashReporter->AddAnnotation(Annotation::PluginHangUIDuration, - hangUIDuration); + nsPrintfCString strHangUIDuration("%u", hangUIDuration); + mCrashReporter->AddNote( + NS_LITERAL_CSTRING("PluginHangUIDuration"), + strHangUIDuration); } } #endif // XP_WIN mozilla::ipc::ScopedProcessHandle geckoChildProcess; bool childOpened = base::OpenProcessHandle(OtherPid(), &geckoChildProcess.rwget()); @@ -1585,18 +1578,17 @@ PluginModuleChromeParent::ProcessFirstMi NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!"); return; } PLUGIN_LOG_DEBUG(("got child minidump: %s", NS_ConvertUTF16toUTF8(mCrashReporter->MinidumpID()).get())); if (!flashProcessType.IsEmpty()) { - mCrashReporter->AddAnnotation(Annotation::FlashProcessDump, - flashProcessType); + mCrashReporter->AddNote(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType); } mCrashReporter->FinalizeCrashReport(); } void PluginModuleParent::ActorDestroy(ActorDestroyReason why) { switch (why) {
--- a/gfx/ipc/GPUProcessManager.cpp +++ b/gfx/ipc/GPUProcessManager.cpp @@ -375,21 +375,22 @@ GPUProcessManager::OnProcessLaunchComple DisableGPUProcess("Failed to create PVsyncBridge endpoints"); return; } mVsyncBridge = VsyncBridgeChild::Create(mVsyncIOThread, mProcessToken, std::move(vsyncChild)); mGPUChild->SendInitVsyncBridge(std::move(vsyncParent)); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GPUProcessStatus, NS_LITERAL_CSTRING("Running")); + NS_LITERAL_CSTRING("GPUProcessStatus"), + NS_LITERAL_CSTRING("Running")); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GPUProcessLaunchCount, - static_cast<int>(mNumProcessAttempts)); + NS_LITERAL_CSTRING("GPUProcessLaunchCount"), + nsPrintfCString("%d", mNumProcessAttempts)); } static bool ShouldLimitDeviceResets(uint32_t count, int32_t deltaMilliseconds) { // We decide to limit by comparing the amount of resets that have happened // and time since the last reset to two prefs. int32_t timeLimit = gfxPrefs::DeviceResetThresholdMilliseconds(); @@ -721,17 +722,17 @@ GPUProcessManager::DestroyProcess() mProcess = nullptr; mGPUChild = nullptr; if (mVsyncBridge) { mVsyncBridge->Close(); mVsyncBridge = nullptr; } CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GPUProcessStatus, + NS_LITERAL_CSTRING("GPUProcessStatus"), NS_LITERAL_CSTRING("Destroyed")); } already_AddRefed<CompositorSession> GPUProcessManager::CreateTopLevelCompositor(nsBaseWidget* aWidget, LayerManager* aLayerManager, CSSToLayoutDeviceScale aScale, const CompositorOptions& aOptions,
--- a/gfx/src/DriverCrashGuard.cpp +++ b/gfx/src/DriverCrashGuard.cpp @@ -160,18 +160,19 @@ DriverCrashGuard::~DriverCrashGuard() // proceed to mark the status as okay. if (GetStatus() != DriverInitStatus::Crashed) { SetStatus(DriverInitStatus::Okay); } } else { dom::ContentChild::GetSingleton()->SendEndDriverCrashGuard(uint32_t(mType)); } - CrashReporter::RemoveCrashReportAnnotation( - CrashReporter::Annotation::GraphicsStartupTest); + // Remove the crash report annotation. + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"), + NS_LITERAL_CSTRING("")); } bool DriverCrashGuard::Crashed() { InitializeIfNeeded(); // Note, we read mCrashDetected instead of GetStatus(), since in child @@ -204,18 +205,18 @@ void DriverCrashGuard::ActivateGuard() { mGuardActivated = true; // Anotate crash reports only if we're a real guard. Otherwise, we could // attribute a random parent process crash to a graphics problem in a child // process. if (mMode != Mode::Proxy) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GraphicsStartupTest, true); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"), + NS_LITERAL_CSTRING("1")); } // If we're in the content process, the rest of the guarding is handled // in the parent. if (XRE_IsContentProcess()) { return; }
--- a/gfx/thebes/DeviceManagerDx.cpp +++ b/gfx/thebes/DeviceManagerDx.cpp @@ -880,18 +880,20 @@ DeviceManagerDx::MaybeResetAndReacquireD if (!HasDeviceReset(&resetReason)) { return false; } if (resetReason != DeviceResetReason::FORCED_RESET) { Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(resetReason)); } + nsPrintfCString reasonString("%d", int(resetReason)); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::DeviceResetReason, int(resetReason)); + NS_LITERAL_CSTRING("DeviceResetReason"), + reasonString); bool createCompositorDevice = !!mCompositorDevice; bool createContentDevice = !!mContentDevice; ResetDevices(); if (createCompositorDevice && !CreateCompositorDevices()) { // Just stop, don't try anything more
--- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -194,38 +194,38 @@ public: /// if the capacity set with the method below is >= 2. We always retain the /// very first critical message, and the latest capacity-1 messages are /// rotated through. Note that we don't expect the total number of times /// this gets called to be large - it is meant for critical errors only. class CrashStatsLogForwarder: public mozilla::gfx::LogForwarder { public: - explicit CrashStatsLogForwarder(CrashReporter::Annotation aKey); + explicit CrashStatsLogForwarder(const char* aKey); void Log(const std::string& aString) override; void CrashAction(LogReason aReason) override; bool UpdateStringsVector(const std::string& aString) override; LoggingRecord LoggingRecordCopy() override; void SetCircularBufferSize(uint32_t aCapacity); private: // Helper for the Log() void UpdateCrashReport(); private: LoggingRecord mBuffer; - CrashReporter::Annotation mCrashCriticalKey; + nsCString mCrashCriticalKey; uint32_t mMaxCapacity; int32_t mIndex; Mutex mMutex; }; -CrashStatsLogForwarder::CrashStatsLogForwarder(CrashReporter::Annotation aKey) +CrashStatsLogForwarder::CrashStatsLogForwarder(const char* aKey) : mBuffer() , mCrashCriticalKey(aKey) , mMaxCapacity(0) , mIndex(-1) , mMutex("CrashStatsLogForwarder") { } @@ -293,23 +293,21 @@ void CrashStatsLogForwarder::UpdateCrash break; } for (auto& it : mBuffer) { message << logAnnotation << Get<0>(it) << "]" << Get<1>(it) << " (t=" << Get<2>(it) << ") "; } nsCString reportString(message.str().c_str()); - nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, - reportString); + nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString); if (annotated != NS_OK) { printf("Crash Annotation %s: %s", - CrashReporter::AnnotationToString(mCrashCriticalKey), - message.str().c_str()); + mCrashCriticalKey.get(), message.str().c_str()); } } class LogForwarderEvent : public Runnable { ~LogForwarderEvent() override = default; public: @@ -918,18 +916,17 @@ gfxPlatform::MaxAllocSize() // pref or whatnot. const int32_t kMinAllocPref = 10000000; return std::max(kMinAllocPref, gfxPrefs::MaxAllocSizeDoNotUseDirectly()); } /* static */ void gfxPlatform::InitMoz2DLogging() { - auto fwd = new CrashStatsLogForwarder( - CrashReporter::Annotation::GraphicsCriticalError); + auto fwd = new CrashStatsLogForwarder("GraphicsCriticalError"); fwd->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength()); mozilla::gfx::Config cfg; cfg.mLogForwarder = fwd; cfg.mMaxTextureSize = gfxPlatform::MaxTextureSize(); cfg.mMaxAllocSize = gfxPlatform::MaxAllocSize(); gfx::Factory::Init(cfg);
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc +++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc @@ -243,34 +243,31 @@ bool Channel::ChannelImpl::CreatePipe(co Mode mode) { DCHECK(server_listen_pipe_ == -1 && pipe_ == -1); // socketpair() pipe_name_ = WideToASCII(channel_id); if (mode == MODE_SERVER) { int pipe_fds[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { - mozilla::ipc::AnnotateCrashReportWithErrno( - CrashReporter::Annotation::IpcCreatePipeSocketPairErrno, errno); + mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeSocketPairErrno", errno); return false; } // Set both ends to be non-blocking. if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { - mozilla::ipc::AnnotateCrashReportWithErrno( - CrashReporter::Annotation::IpcCreatePipeFcntlErrno, errno); + mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeFcntlErrno", errno); IGNORE_EINTR(close(pipe_fds[0])); IGNORE_EINTR(close(pipe_fds[1])); return false; } if (!SetCloseOnExec(pipe_fds[0]) || !SetCloseOnExec(pipe_fds[1])) { - mozilla::ipc::AnnotateCrashReportWithErrno( - CrashReporter::Annotation::IpcCreatePipeCloExecErrno, errno); + mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeCloExecErrno", errno); IGNORE_EINTR(close(pipe_fds[0])); IGNORE_EINTR(close(pipe_fds[1])); return false; } pipe_ = pipe_fds[0]; client_pipe_ = pipe_fds[1];
--- a/ipc/glue/CrashReporterClient.cpp +++ b/ipc/glue/CrashReporterClient.cpp @@ -21,18 +21,17 @@ CrashReporterClient::CrashReporterClient } CrashReporterClient::~CrashReporterClient() { MOZ_COUNT_DTOR(CrashReporterClient); } void -CrashReporterClient::AnnotateCrashReport(CrashReporter::Annotation aKey, - const nsCString& aData) +CrashReporterClient::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData) { StaticMutexAutoLock lock(sLock); mMetadata->AnnotateCrashReport(aKey, aData); } void CrashReporterClient::AppendAppNotes(const nsCString& aData) {
--- a/ipc/glue/CrashReporterClient.h +++ b/ipc/glue/CrashReporterClient.h @@ -60,18 +60,17 @@ public: aOutShmem); } static void InitSingletonWithShmem(const Shmem& aShmem); static void DestroySingleton(); static RefPtr<CrashReporterClient> GetSingleton(); - void AnnotateCrashReport(CrashReporter::Annotation aKey, - const nsCString& aData); + void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData); void AppendAppNotes(const nsCString& aData); private: explicit CrashReporterClient(const Shmem& aShmem); ~CrashReporterClient(); private: static StaticMutex sLock;
--- a/ipc/glue/CrashReporterHost.cpp +++ b/ipc/glue/CrashReporterHost.cpp @@ -60,17 +60,17 @@ CrashReporterHost::AdoptMinidump(nsIFile } bool CrashReporterHost::FinalizeCrashReport() { MOZ_ASSERT(!mFinalized); MOZ_ASSERT(HasMinidump()); - CrashReporter::AnnotationTable annotations; + CrashReporter::AnnotationTable notes; nsAutoCString type; switch (mProcessType) { case GeckoProcessType_Content: type = NS_LITERAL_CSTRING("content"); break; case GeckoProcessType_Plugin: case GeckoProcessType_GMPlugin: @@ -78,33 +78,32 @@ CrashReporterHost::FinalizeCrashReport() break; case GeckoProcessType_GPU: type = NS_LITERAL_CSTRING("gpu"); break; default: NS_ERROR("unknown process type"); break; } - annotations[CrashReporter::Annotation::ProcessType] = type; + notes.Put(NS_LITERAL_CSTRING("ProcessType"), type); char startTime[32]; SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime)); - annotations[CrashReporter::Annotation::StartupTime] = - nsDependentCString(startTime); + notes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime)); // We might not have shmem (for example, when running crashreporter tests). if (mShmem.IsReadable()) { - CrashReporterMetadataShmem::ReadAppNotes(mShmem, annotations); + CrashReporterMetadataShmem::ReadAppNotes(mShmem, ¬es); } - CrashReporter::AppendExtraData(mDumpID, mExtraAnnotations); - CrashReporter::AppendExtraData(mDumpID, annotations); + CrashReporter::AppendExtraData(mDumpID, mExtraNotes); + CrashReporter::AppendExtraData(mDumpID, notes); - // Use mExtraAnnotations, since NotifyCrashService looks for "PluginHang" - // which is set in the parent process. - NotifyCrashService(mProcessType, mDumpID, mExtraAnnotations); + // Use mExtraNotes, since NotifyCrashService looks for "PluginHang" which is + // set in the parent process. + NotifyCrashService(mProcessType, mDumpID, &mExtraNotes); mFinalized = true; return true; } namespace { class GenerateMinidumpShutdownBlocker : public nsIAsyncShutdownBlocker { public: @@ -217,21 +216,21 @@ CrashReporterHost::GenerateMinidumpAndPa getter_AddRefs(mTargetDump), std::move(callback), aAsync); } /* static */ void CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType, const nsString& aChildDumpID, - const AnnotationTable& aNotes) + const AnnotationTable* aNotes) { if (!NS_IsMainThread()) { RefPtr<Runnable> runnable = NS_NewRunnableFunction( - "ipc::CrashReporterHost::NotifyCrashService", [&]() -> void { + "ipc::CrashReporterHost::NotifyCrashService", [=]() -> void { CrashReporterHost::NotifyCrashService( aProcessType, aChildDumpID, aNotes); }); RefPtr<nsIThread> mainThread = do_GetMainThread(); SyncRunnable::DispatchToThread(mainThread, runnable); return; } @@ -251,18 +250,19 @@ CrashReporterHost::NotifyCrashService(Ge switch (aProcessType) { case GeckoProcessType_Content: processType = nsICrashService::PROCESS_TYPE_CONTENT; telemetryKey.AssignLiteral("content"); break; case GeckoProcessType_Plugin: { processType = nsICrashService::PROCESS_TYPE_PLUGIN; telemetryKey.AssignLiteral("plugin"); - nsCString val = aNotes[CrashReporter::Annotation::PluginHang]; - if (val.Equals(NS_LITERAL_CSTRING("1"))) { + nsAutoCString val; + if (aNotes->Get(NS_LITERAL_CSTRING("PluginHang"), &val) && + val.EqualsLiteral("1")) { crashType = nsICrashService::CRASH_TYPE_HANG; telemetryKey.AssignLiteral("pluginhang"); } break; } case GeckoProcessType_GMPlugin: processType = nsICrashService::PROCESS_TYPE_GMPLUGIN; telemetryKey.AssignLiteral("gmplugin"); @@ -277,41 +277,15 @@ CrashReporterHost::NotifyCrashService(Ge } RefPtr<Promise> promise; crashService->AddCrash(processType, crashType, aChildDumpID, getter_AddRefs(promise)); Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1); } void -CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey, bool aValue) -{ - mExtraAnnotations[aKey] = aValue ? NS_LITERAL_CSTRING("1") - : NS_LITERAL_CSTRING("0"); -} - -void -CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey, - int aValue) +CrashReporterHost::AddNote(const nsCString& aKey, const nsCString& aValue) { - nsAutoCString valueString; - valueString.AppendInt(aValue); - mExtraAnnotations[aKey] = valueString; -} - -void -CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey, - unsigned int aValue) -{ - nsAutoCString valueString; - valueString.AppendInt(aValue); - mExtraAnnotations[aKey] = valueString; -} - -void -CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey, - const nsCString& aValue) -{ - mExtraAnnotations[aKey] = aValue; + mExtraNotes.Put(aKey, aValue); } } // namespace ipc } // namespace mozilla
--- a/ipc/glue/CrashReporterHost.h +++ b/ipc/glue/CrashReporterHost.h @@ -125,22 +125,19 @@ public: // This is a static helper function to notify the crash service that a // crash has occurred. When PCrashReporter is removed, we can make this // a member function. This can be called from any thread, and if not // called from the main thread, will post a synchronous message to the // main thread. static void NotifyCrashService( GeckoProcessType aProcessType, const nsString& aChildDumpID, - const AnnotationTable& aNotes); + const AnnotationTable* aNotes); - void AddAnnotation(CrashReporter::Annotation aKey, bool aValue); - void AddAnnotation(CrashReporter::Annotation aKey, int aValue); - void AddAnnotation(CrashReporter::Annotation aKey, unsigned int aValue); - void AddAnnotation(CrashReporter::Annotation aKey, const nsCString& aValue); + void AddNote(const nsCString& aKey, const nsCString& aValue); bool HasMinidump() const { return !mDumpID.IsEmpty(); } const nsString& MinidumpID() const { MOZ_ASSERT(HasMinidump()); return mDumpID; } @@ -150,17 +147,17 @@ private: const nsString& aChildDumpID); private: CallbackWrapper<bool> mCreateMinidumpCallback; GeckoProcessType mProcessType; Shmem mShmem; ThreadId mThreadId; time_t mStartTime; - AnnotationTable mExtraAnnotations; + AnnotationTable mExtraNotes; nsString mDumpID; bool mFinalized; nsCOMPtr<nsIFile> mTargetDump; }; } // namespace ipc } // namespace mozilla
--- a/ipc/glue/CrashReporterMetadataShmem.cpp +++ b/ipc/glue/CrashReporterMetadataShmem.cpp @@ -1,24 +1,21 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "CrashReporterMetadataShmem.h" #include "mozilla/Attributes.h" -#include "mozilla/EnumeratedRange.h" #include "nsISupportsImpl.h" namespace mozilla { namespace ipc { -using CrashReporter::Annotation; - enum class EntryType : uint8_t { None, Annotation, }; CrashReporterMetadataShmem::CrashReporterMetadataShmem(const Shmem& aShmem) : mShmem(aShmem) { @@ -26,42 +23,41 @@ CrashReporterMetadataShmem::CrashReporte } CrashReporterMetadataShmem::~CrashReporterMetadataShmem() { MOZ_COUNT_DTOR(CrashReporterMetadataShmem); } void -CrashReporterMetadataShmem::AnnotateCrashReport(Annotation aKey, - const nsCString& aData) +CrashReporterMetadataShmem::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData) { - mAnnotations[aKey] = aData; + mNotes.Put(aKey, aData); SyncNotesToShmem(); } void CrashReporterMetadataShmem::AppendAppNotes(const nsCString& aData) { mAppNotes.Append(aData); - mAnnotations[Annotation::Notes] = mAppNotes; + mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes); SyncNotesToShmem(); } class MOZ_STACK_CLASS MetadataShmemWriter { public: explicit MetadataShmemWriter(const Shmem& aShmem) : mCursor(aShmem.get<uint8_t>()), mEnd(mCursor + aShmem.Size<uint8_t>()) { *mCursor = uint8_t(EntryType::None); } - MOZ_MUST_USE bool WriteAnnotation(Annotation aKey, const nsCString& aValue) { + MOZ_MUST_USE bool WriteAnnotation(const nsCString& aKey, const nsCString& aValue) { // This shouldn't happen because Commit() guarantees mCursor < mEnd. But // we might as well be safe. if (mCursor >= mEnd) { return false; } // Save the current position so we can write the entry type if the entire // entry fits. @@ -124,21 +120,21 @@ private: uint8_t* mEnd; }; void CrashReporterMetadataShmem::SyncNotesToShmem() { MetadataShmemWriter writer(mShmem); - for (auto key : MakeEnumeratedRange(Annotation::Count)) { - if (!mAnnotations[key].IsEmpty()) { - if (!writer.WriteAnnotation(key, mAnnotations[key])) { - return; - } + for (auto it = mNotes.Iter(); !it.Done(); it.Next()) { + nsCString key = nsCString(it.Key()); + nsCString value = nsCString(it.Data()); + if (!writer.WriteAnnotation(key, value)) { + return; } } } // Helper class to iterate over metadata entries encoded in shmem. class MOZ_STACK_CLASS MetadataShmemReader { public: @@ -161,37 +157,36 @@ public: void Next() { if (mCursor < mEnd) { mEntryType = EntryType(*mCursor++); } else { mEntryType = EntryType::None; } } - template <typename T> - bool Read(T* aOut) { - return Read(aOut, sizeof(T)); - } - bool Read(nsCString& aOut) { uint32_t length = 0; if (!Read(&length)) { return false; } const uint8_t* src = Read(length); if (!src) { return false; } aOut.Assign((const char *)src, length); return true; } private: + template <typename T> + bool Read(T* aOut) { + return Read(aOut, sizeof(T)); + } bool Read(void* aOut, size_t aLength) { const uint8_t* src = Read(aLength); if (!src) { return false; } memcpy(aOut, src, aLength); return true; } @@ -209,29 +204,27 @@ private: private: const uint8_t* mCursor; const uint8_t* mEnd; EntryType mEntryType; }; void -CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem, - AnnotationTable& aNotes) +CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes) { for (MetadataShmemReader reader(aShmem); !reader.Done(); reader.Next()) { switch (reader.Type()) { case EntryType::Annotation: { - Annotation key; - nsCString value; - if (!reader.Read(&key) || !reader.Read(value)) { + nsCString key, value; + if (!reader.Read(key) || !reader.Read(value)) { return; } - aNotes[key] = value; + aNotes->Put(key, value); break; } default: NS_ASSERTION(false, "Unknown metadata entry type"); break; } } }
--- a/ipc/glue/CrashReporterMetadataShmem.h +++ b/ipc/glue/CrashReporterMetadataShmem.h @@ -20,29 +20,27 @@ class CrashReporterMetadataShmem typedef mozilla::ipc::Shmem Shmem; typedef CrashReporter::AnnotationTable AnnotationTable; public: explicit CrashReporterMetadataShmem(const Shmem& aShmem); ~CrashReporterMetadataShmem(); // Metadata writers. These must only be called in child processes. - void AnnotateCrashReport(CrashReporter::Annotation aKey, - const nsCString& aData); + void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData); void AppendAppNotes(const nsCString& aData); - static void ReadAppNotes(const Shmem& aShmem, - CrashReporter::AnnotationTable& aNotes); + static void ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes); private: void SyncNotesToShmem(); private: Shmem mShmem; - AnnotationTable mAnnotations; + AnnotationTable mNotes; nsCString mAppNotes; }; } // namespace ipc } // namespace mozilla #endif // mozilla_ipc_CrashReporterMetadataShmem_h
--- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -132,24 +132,22 @@ struct EnumSerializer { static void Write(Message* aMsg, const paramType& aValue) { MOZ_RELEASE_ASSERT(EnumValidator::IsLegalValue(aValue)); WriteParam(aMsg, uintParamType(aValue)); } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { uintParamType value; if (!ReadParam(aMsg, aIter, &value)) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCReadErrorReason, - NS_LITERAL_CSTRING("Bad iter")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"), + NS_LITERAL_CSTRING("Bad iter")); return false; } else if (!EnumValidator::IsLegalValue(paramType(value))) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCReadErrorReason, - NS_LITERAL_CSTRING("Illegal value")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"), + NS_LITERAL_CSTRING("Illegal value")); return false; } *aResult = paramType(value); return true; } }; template <typename E,
--- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -769,18 +769,19 @@ MessageChannel::CanSend() const MonitorAutoLock lock(*mMonitor); return Connected(); } void MessageChannel::WillDestroyCurrentMessageLoop() { #if defined(DEBUG) - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IPCFatalErrorProtocol, - nsDependentCString(mName)); + CrashReporter::AnnotateCrashReport( + NS_LITERAL_CSTRING("IPCFatalErrorProtocol"), + nsDependentCString(mName)); MOZ_CRASH("MessageLoop destroyed before MessageChannel that's bound to it"); #endif // Clear mWorkerThread to avoid posting to it in the future. MonitorAutoLock lock(*mMonitor); mWorkerLoop = nullptr; } @@ -798,17 +799,18 @@ MessageChannel::Clear() // before mListener. But just to be safe, mListener is a weak pointer. #if !defined(ANDROID) // KillHard shutdowns can occur with the channel in connected state. We are // already collecting crash dump data about KillHard shutdowns and we // shouldn't intentionally crash here. if (!Unsound_IsClosed() && !mInKillHardShutdown) { CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCFatalErrorProtocol, nsDependentCString(mName)); + NS_LITERAL_CSTRING("IPCFatalErrorProtocol"), + nsDependentCString(mName)); switch (mChannelState) { case ChannelOpening: MOZ_CRASH("MessageChannel destroyed without being closed " \ "(mChannelState == ChannelOpening)."); break; case ChannelConnected: MOZ_CRASH("MessageChannel destroyed without being closed " \ "(mChannelState == ChannelConnected).");
--- a/ipc/glue/MessageLink.cpp +++ b/ipc/glue/MessageLink.cpp @@ -154,22 +154,18 @@ ProcessLink::EchoMessage(Message *msg) msg)); // OnEchoMessage takes ownership of |msg| } void ProcessLink::SendMessage(Message *msg) { if (msg->size() > IPC::Channel::kMaximumMessageSize) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCMessageName, - nsDependentCString(msg->name())); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCMessageSize, - static_cast<int>(msg->size())); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageName"), nsDependentCString(msg->name())); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageSize"), nsPrintfCString("%d", msg->size())); MOZ_CRASH("IPC message size is too large"); } if (!mChan->mIsPostponingSends) { mChan->AssertWorkerThread(); } mChan->mMonitor->AssertCurrentThreadOwns();
--- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -206,17 +206,17 @@ bool DuplicateHandle(HANDLE aSourceHandl #endif // Finally, see if we already have access to the process. ScopedProcessHandle targetProcess(OpenProcess(PROCESS_DUP_HANDLE, FALSE, aTargetProcessId)); if (!targetProcess) { CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCTransportFailureReason, + NS_LITERAL_CSTRING("IPCTransportFailureReason"), NS_LITERAL_CSTRING("Failed to open target process.")); return false; } return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle, targetProcess, aTargetHandle, aDesiredAccess, FALSE, aOptions); } @@ -228,28 +228,30 @@ AnnotateSystemError() int64_t error = 0; #if defined(XP_WIN) error = ::GetLastError(); #elif defined(OS_POSIX) error = errno; #endif if (error) { CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCSystemError, + NS_LITERAL_CSTRING("IPCSystemError"), nsPrintfCString("%" PRId64, error)); } } #if defined(XP_MACOSX) void -AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error) +AnnotateCrashReportWithErrno(const char* tag, int error) { - CrashReporter::AnnotateCrashReport(tag, error); + CrashReporter::AnnotateCrashReport( + nsCString(tag), + nsPrintfCString("%d", error)); } -#endif // defined(XP_MACOSX) +#endif void LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid, const char* aContextDescription, uint32_t aMessageId, MessageDirection aDirection) { nsPrintfCString logMessage("[time: %" PRId64 "][%d%s%d] [%s] %s %s\n", @@ -283,19 +285,18 @@ FatalError(const char* aMsg, bool aIsPar nsAutoCString formattedMessage("IPDL error: \""); formattedMessage.AppendASCII(aMsg); if (aIsParent) { // We're going to crash the parent process because at this time // there's no other really nice way of getting a minidump out of // this process if we're off the main thread. formattedMessage.AppendLiteral("\". Intentionally crashing."); NS_ERROR(formattedMessage.get()); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::IPCFatalErrorMsg, - nsDependentCString(aMsg)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorMsg"), + nsDependentCString(aMsg)); AnnotateSystemError(); #ifndef FUZZING MOZ_CRASH("IPC FatalError in the parent process!"); #endif } else { formattedMessage.AppendLiteral("\". abort()ing as a result."); #ifndef FUZZING MOZ_CRASH_UNSAFE_OOL(formattedMessage.get());
--- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -28,17 +28,16 @@ #include "mozilla/LinkedList.h" #include "mozilla/Maybe.h" #include "mozilla/MozPromise.h" #include "mozilla/Mutex.h" #include "mozilla/NotNull.h" #include "mozilla/Scoped.h" #include "mozilla/UniquePtr.h" #include "MainThreadUtils.h" -#include "nsICrashReporter.h" #include "nsILabelableRunnable.h" #if defined(ANDROID) && defined(DEBUG) #include <android/log.h> #endif template<typename T> class nsTHashtable; template<typename T> class nsPtrHashKey; @@ -910,19 +909,19 @@ private: bool mValid; mozilla::ipc::Transport::Mode mMode; TransportDescriptor mTransport; ProcessId mMyPid, mOtherPid; }; #if defined(XP_MACOSX) -void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error); +void AnnotateCrashReportWithErrno(const char* tag, int error); #else -static inline void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error) +static inline void AnnotateCrashReportWithErrno(const char* tag, int error) {} #endif // This function is used internally to create a pair of Endpoints. See the // comment above Endpoint for a description of how it might be used. template<class PFooParent, class PFooChild> nsresult CreateEndpoints(const PrivateIPDLInterface& aPrivate, @@ -932,18 +931,17 @@ CreateEndpoints(const PrivateIPDLInterfa Endpoint<PFooChild>* aChildEndpoint) { MOZ_RELEASE_ASSERT(aParentDestPid); MOZ_RELEASE_ASSERT(aChildDestPid); TransportDescriptor parentTransport, childTransport; nsresult rv; if (NS_FAILED(rv = CreateTransport(aParentDestPid, &parentTransport, &childTransport))) { - AnnotateCrashReportWithErrno( - CrashReporter::Annotation::IpcCreateEndpointsNsresult, int(rv)); + AnnotateCrashReportWithErrno("IpcCreateEndpointsNsresult", int(rv)); return rv; } *aParentEndpoint = Endpoint<PFooParent>(aPrivate, mozilla::ipc::Transport::MODE_SERVER, parentTransport, aParentDestPid, aChildDestPid); *aChildEndpoint = Endpoint<PFooChild>(aPrivate, mozilla::ipc::Transport::MODE_CLIENT, childTransport, aChildDestPid, aParentDestPid);
--- a/ipc/glue/Transport_posix.cpp +++ b/ipc/glue/Transport_posix.cpp @@ -35,23 +35,21 @@ CreateTransport(base::ProcessId aProcIdO if (fd1 < 0 || fd2 < 0) { return NS_ERROR_TRANSPORT_INIT; } // The Transport closes these fds when it goes out of scope, so we // dup them here fd1 = dup(fd1); if (fd1 < 0) { - AnnotateCrashReportWithErrno( - CrashReporter::Annotation::IpcCreateTransportDupErrno, errno); + AnnotateCrashReportWithErrno("IpcCreateTransportDupErrno", errno); } fd2 = dup(fd2); if (fd2 < 0) { - AnnotateCrashReportWithErrno( - CrashReporter::Annotation::IpcCreateTransportDupErrno, errno); + AnnotateCrashReportWithErrno("IpcCreateTransportDupErrno", errno); } if (fd1 < 0 || fd2 < 0) { IGNORE_EINTR(close(fd1)); IGNORE_EINTR(close(fd2)); return NS_ERROR_DUPLICATE_HANDLE; }
--- a/ipc/mscom/COMPtrHolder.h +++ b/ipc/mscom/COMPtrHolder.h @@ -205,19 +205,18 @@ struct ParamTraits<mozilla::mscom::COMPt return false; } } typename paramType::EnvType env; mozilla::mscom::ProxyStream proxyStream(_IID, buf.get(), length, &env); if (!proxyStream.IsValid()) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ProxyStreamValid, - NS_LITERAL_CSTRING("false")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamValid"), + NS_LITERAL_CSTRING("false")); return false; } typename paramType::COMPtrType ptr; if (!proxyStream.GetInterface(mozilla::mscom::getter_AddRefs(ptr))) { return false; }
--- a/ipc/mscom/ProxyStream.cpp +++ b/ipc/mscom/ProxyStream.cpp @@ -39,18 +39,17 @@ ProxyStream::ProxyStream() // reconstructing the stream from a buffer anyway. ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf, const int aInitBufSize, Environment* aEnv) : mGlobalLockedBuf(nullptr) , mHGlobal(nullptr) , mBufSize(aInitBufSize) , mPreserveStream(false) { - CrashReporter::Annotation kCrashReportKey = - CrashReporter::Annotation::ProxyStreamUnmarshalStatus; + NS_NAMED_LITERAL_CSTRING(kCrashReportKey, "ProxyStreamUnmarshalStatus"); if (!aInitBufSize) { CrashReporter::AnnotateCrashReport(kCrashReportKey, NS_LITERAL_CSTRING("!aInitBufSize")); // We marshaled a nullptr. Nothing else to do here. return; } @@ -132,40 +131,43 @@ ProxyStream::ProxyStream(REFIID aIID, co EnsureMTA mta(marshalFn); } mStream = nullptr; if (FAILED(unmarshalResult) || !mUnmarshaledProxy) { nsPrintfCString hrAsStr("0x%08X", unmarshalResult); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::CoUnmarshalInterfaceResult, hrAsStr); + NS_LITERAL_CSTRING("CoUnmarshalInterfaceResult"), hrAsStr); AnnotateInterfaceRegistration(aIID); if (!mUnmarshaledProxy) { CrashReporter::AnnotateCrashReport(kCrashReportKey, NS_LITERAL_CSTRING("!mUnmarshaledProxy")); } #if defined(ACCESSIBILITY) AnnotateClassRegistration(CLSID_AccessibleHandler); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::UnmarshalActCtx, strActCtx); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::UnmarshalActCtxManifestPath, - NS_ConvertUTF16toUTF8(manifestPath)); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::A11yHandlerRegistered, - a11y::IsHandlerRegistered() ? NS_LITERAL_CSTRING("true") - : NS_LITERAL_CSTRING("false")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtx"), + strActCtx); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtxManifestPath"), + NS_ConvertUTF16toUTF8(manifestPath)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("A11yHandlerRegistered"), + a11y::IsHandlerRegistered() ? + NS_LITERAL_CSTRING("true") : + NS_LITERAL_CSTRING("false")); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ExpectedStreamLen, expectedStreamLen); + nsAutoCString strExpectedStreamLen; + strExpectedStreamLen.AppendInt(expectedStreamLen); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ExpectedStreamLen"), + strExpectedStreamLen); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ActualStreamLen, aInitBufSize); + nsAutoCString actualStreamLen; + actualStreamLen.AppendInt(aInitBufSize); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ActualStreamLen"), + actualStreamLen); #endif // defined(ACCESSIBILITY) } } ProxyStream::ProxyStream(ProxyStream&& aOther) : mGlobalLockedBuf(nullptr) , mHGlobal(nullptr) , mBufSize(0) @@ -353,66 +355,69 @@ ProxyStream::ProxyStream(REFIID aIID, IU } else { // When marshaling in child processes, we want to force the MTA. EnsureMTA mta(marshalFn); } if (FAILED(createStreamResult)) { nsPrintfCString hrAsStr("0x%08X", createStreamResult); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::CreateStreamOnHGlobalFailure, hrAsStr); + NS_LITERAL_CSTRING("CreateStreamOnHGlobalFailure"), + hrAsStr); } if (FAILED(marshalResult)) { AnnotateInterfaceRegistration(aIID); nsPrintfCString hrAsStr("0x%08X", marshalResult); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::CoMarshalInterfaceFailure, hrAsStr); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::MarshalActCtxManifestPath, - NS_ConvertUTF16toUTF8(manifestPath)); + NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("MarshalActCtxManifestPath"), + NS_ConvertUTF16toUTF8(manifestPath)); } if (FAILED(statResult)) { nsPrintfCString hrAsStr("0x%08X", statResult); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StatFailure, - hrAsStr); + CrashReporter::AnnotateCrashReport( + NS_LITERAL_CSTRING("StatFailure"), + hrAsStr); } if (FAILED(getHGlobalResult)) { nsPrintfCString hrAsStr("0x%08X", getHGlobalResult); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GetHGlobalFromStreamFailure, hrAsStr); + NS_LITERAL_CSTRING("GetHGlobalFromStreamFailure"), + hrAsStr); } mStream = std::move(stream); if (streamSize) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ProxyStreamSizeFrom, - NS_LITERAL_CSTRING("IStream::Stat")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"), + NS_LITERAL_CSTRING("IStream::Stat")); mBufSize = streamSize; } if (!hglobal) { return; } mGlobalLockedBuf = reinterpret_cast<BYTE*>(::GlobalLock(hglobal)); mHGlobal = hglobal; // If we couldn't get the stream size directly from mStream, we may use // the size of the memory block allocated by the HGLOBAL, though it might // be larger than the actual stream size. if (!streamSize) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ProxyStreamSizeFrom, - NS_LITERAL_CSTRING("GlobalSize")); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"), + NS_LITERAL_CSTRING("GlobalSize")); mBufSize = static_cast<int>(::GlobalSize(hglobal)); } - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProxyStreamSize, - mBufSize); + nsAutoCString strBufSize; + strBufSize.AppendInt(mBufSize); + + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSize"), + strBufSize); } } // namespace mscom } // namespace mozilla
--- a/ipc/mscom/RegistrationAnnotator.cpp +++ b/ipc/mscom/RegistrationAnnotator.cpp @@ -371,25 +371,26 @@ AnnotateInterfaceRegistration(REFIID aIi json.EndObject(); json.StartObjectProperty("HKCU", style); AnnotateInterfaceRegistrationForHive(json, HKEY_CURRENT_USER, aIid, style); json.EndObject(); json.End(); - CrashReporter::Annotation annotationKey; + nsAutoCString annotationKey; + annotationKey.AppendLiteral("InterfaceRegistrationInfo"); if (XRE_IsParentProcess()) { - annotationKey = CrashReporter::Annotation::InterfaceRegistrationInfoParent; + annotationKey.AppendLiteral("Parent"); } else { - annotationKey = CrashReporter::Annotation::InterfaceRegistrationInfoChild; + annotationKey.AppendLiteral("Child"); } - CrashReporter::AnnotateCrashReport( - annotationKey, - static_cast<CStringWriter*>(json.WriteFunc())->Get()); + + CrashReporter::AnnotateCrashReport(annotationKey, + static_cast<CStringWriter*>(json.WriteFunc())->Get()); } void AnnotateClassRegistration(REFCLSID aClsid) { #if defined(DEBUG) const JSONWriter::CollectionStyle style = JSONWriter::MultiLineStyle; #else @@ -408,21 +409,22 @@ AnnotateClassRegistration(REFCLSID aClsi json.EndObject(); json.StartObjectProperty("HKCU", style); AnnotateClsidRegistrationForHive(json, HKEY_CURRENT_USER, strClsid, style); json.EndObject(); json.End(); - CrashReporter::Annotation annotationKey; + nsAutoCString annotationKey; + annotationKey.AppendLiteral("ClassRegistrationInfo"); if (XRE_IsParentProcess()) { - annotationKey = CrashReporter::Annotation::ClassRegistrationInfoParent; + annotationKey.AppendLiteral("Parent"); } else { - annotationKey = CrashReporter::Annotation::ClassRegistrationInfoChild; + annotationKey.AppendLiteral("Child"); } CrashReporter::AnnotateCrashReport(annotationKey, static_cast<CStringWriter*>(json.WriteFunc())->Get()); } } // namespace mscom } // namespace mozilla
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -15,17 +15,16 @@ #ifdef XP_WIN #include <windows.h> #endif #include "jsapi.h" #include "js/Printf.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" -#include "nsExceptionHandler.h" #include "nsIComponentManager.h" #include "mozilla/Module.h" #include "nsIFile.h" #include "mozJSComponentLoader.h" #include "mozJSLoaderUtils.h" #include "nsIXPConnect.h" #include "nsIObserverService.h" #include "nsIScriptSecurityManager.h" @@ -52,16 +51,20 @@ #include "mozilla/ResultExtensions.h" #include "mozilla/ScriptPreloader.h" #include "mozilla/dom/DOMPrefs.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/ResultExtensions.h" #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; using namespace xpc; using namespace JS; static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1"; @@ -355,47 +358,51 @@ ResolveModuleObjectProperty(JSContext* a } if (found) { return lexical; } } return aModObj; } +#ifdef MOZ_CRASHREPORTER static mozilla::Result<nsCString, nsresult> ReadScript(ComponentLoaderInfo& aInfo); static nsresult -AnnotateScriptContents(CrashReporter::Annotation aName, const nsACString& aURI) +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( - CrashReporter::Annotation::nsAsyncShutdownComponent, + NS_LITERAL_CSTRING("nsAsyncShutdownComponent"), NS_LITERAL_CSTRING("resource://gre/components/nsAsyncShutdown.js")); Unused << AnnotateScriptContents( - CrashReporter::Annotation::AsyncShutdownModule, + 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) { if (!NS_IsMainThread()) {
--- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -2882,19 +2882,20 @@ Gecko_AddBufferToCrashReport(const void* { MOZ_ASSERT(NS_IsMainThread()); nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1"); NS_ENSURE_TRUE_VOID(cr); cr->RegisterAppMemory((uint64_t) addr, len); } void -Gecko_AnnotateCrashReport(uint32_t key, const char* value_str) +Gecko_AnnotateCrashReport(const char* key_str, const char* value_str) { MOZ_ASSERT(NS_IsMainThread()); + nsDependentCString key(key_str); nsDependentCString value(value_str); nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1"); NS_ENSURE_TRUE_VOID(cr); cr->AnnotateCrashReport(key, value); } void Gecko_ContentList_AppendAll(
--- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -678,17 +678,17 @@ void Gecko_UnregisterProfilerThread(); bool Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed, const nsACString* aPattern, mozilla::css::DocumentMatchingFunction); // Allocator hinting. void Gecko_SetJemallocThreadLocalArena(bool enabled); void Gecko_AddBufferToCrashReport(const void* addr, size_t len); -void Gecko_AnnotateCrashReport(uint32_t key, const char* value_str); +void Gecko_AnnotateCrashReport(const char* key_str, const char* value_str); // Pseudo-element flags. #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ const uint32_t SERVO_CSS_PSEUDO_ELEMENT_FLAGS_##name_ = flags_; #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT #define SERVO_BINDING_FUNC(name_, return_, ...) return_ name_(__VA_ARGS__);
--- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -707,19 +707,18 @@ AnnotateCrashReport(nsIURI* aURI) } } delete find; } } else { annotation.AppendLiteral("No GRE omnijar\n"); } - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::SheetLoadFailure, - NS_ConvertUTF16toUTF8(annotation)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SheetLoadFailure"), + NS_ConvertUTF16toUTF8(annotation)); } static void ErrorLoadingSheet(nsIURI* aURI, const char* aMsg, FailureAction aFailureAction) { nsPrintfCString errorMessage("%s loading built-in stylesheet '%s'", aMsg, aURI ? aURI->GetSpecOrDefault().get() : "");
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCrashPingBuilder.java +++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCrashPingBuilder.java @@ -3,17 +3,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.telemetry.pingbuilders; import android.util.Log; -import org.mozilla.gecko.CrashReporterConstants; import org.mozilla.gecko.sync.ExtendedJSONObject; import org.mozilla.gecko.sync.NonObjectJSONException; import org.mozilla.gecko.util.StringUtils; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -31,16 +30,50 @@ import java.util.TimeZone; public class TelemetryCrashPingBuilder extends TelemetryPingBuilder { private static final String LOGTAG = "GeckoTelemetryCrashPingBuilder"; private static final int PING_VERSION = 1; private static final String ISO8601_DATE = "yyyy-MM-dd"; private static final String ISO8601_DATE_HOURS = "yyyy-MM-dd'T'HH':00:00.000Z'"; + // The following list should be kept in sync with the one in CrashManager.jsm + private static final String[] ANNOTATION_WHITELIST = { + "AsyncShutdownTimeout", + "AvailablePageFile", + "AvailablePhysicalMemory", + "AvailableVirtualMemory", + "BlockedDllList", + "BlocklistInitFailed", + "BuildID", + "ContainsMemoryReport", + "CrashTime", + "EventLoopNestingLevel", + "ipc_channel_error", + "IsGarbageCollecting", + "LowCommitSpaceEvents", + "MozCrashReason", + "OOMAllocationSize", + "ProductID", + "ProductName", + "ReleaseChannel", + "RemoteType", + "SecondsSinceLastCrash", + "ShutdownProgress", + "StartupCrash", + "SystemMemoryUsePercentage", + "TextureUsage", + "TotalPageFile", + "TotalPhysicalMemory", + "TotalVirtualMemory", + "UptimeTS", + "User32BeforeBlocklist", + "Version", + }; + public TelemetryCrashPingBuilder(String crashId, String clientId, HashMap<String, String> annotations) { super(TelemetryPingBuilder.UNIFIED_TELEMETRY_VERSION); payload.put("type", "crash"); payload.put("id", docID); payload.put("version", TelemetryPingBuilder.UNIFIED_TELEMETRY_VERSION); payload.put("creationDate", currentDate(ISO8601_DATE_HOURS)); payload.put("clientId", clientId); @@ -140,17 +173,17 @@ public class TelemetryCrashPingBuilder e * * @param annotations A map holding the crash annotations * @returns A JSON object representing the ping's metadata node */ private static ExtendedJSONObject createMetadataNode(HashMap<String, String> annotations) { ExtendedJSONObject node = new ExtendedJSONObject(); for (Entry<String, String> pair : annotations.entrySet()) { - if (Arrays.binarySearch(CrashReporterConstants.ANNOTATION_WHITELIST, pair.getKey()) >= 0) { + if (Arrays.binarySearch(ANNOTATION_WHITELIST, pair.getKey()) >= 0) { node.put(pair.getKey(), pair.getValue()); } } return node; } /**
--- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -111,37 +111,31 @@ with Files('../app/src/*/res/menu/browse DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME'] FINAL_TARGET_PP_FILES += ['package-name.txt.in'] GENERATED_FILES += [ 'AndroidManifest.xml', 'generated/preprocessed/org/mozilla/gecko/AdjustConstants.java', 'generated/preprocessed/org/mozilla/gecko/AppConstants.java', - 'generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java', 'generated/preprocessed/org/mozilla/gecko/MmaConstants.java', ] x = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/AdjustConstants.java'] x.script = 'generate_build_config.py:generate_java' x.inputs += ['AdjustConstants.java.in'] y = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/AppConstants.java'] y.script = 'generate_build_config.py:generate_java' y.inputs += ['AppConstants.java.in'] y = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/MmaConstants.java'] y.script = 'generate_build_config.py:generate_java' y.inputs += ['MmaConstants.java.in'] z = GENERATED_FILES['AndroidManifest.xml'] z.script = 'generate_build_config.py:generate_android_manifest' z.inputs += ['AndroidManifest.xml.in'] -# Generate CrashReporterConstants.java -crash_reporter_constants = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java'] -crash_reporter_constants.script = '/toolkit/crashreporter/generate_crash_reporter_sources.py:emit_class' -crash_reporter_constants.inputs += ['/toolkit/crashreporter/CrashAnnotations.yaml'] - # Regular builds invoke `libs` targets that localize files with no AB_CD set # into the default resources (res/{values,raw}). # # Multi-locale builds invoke `chrome-%` targets that localize files into # locale-specific resources (res/{values,raw}-AB-rCD). Single-locale repacks # invoke `libs AB_CD=$*` targets that localize files into the default resources # (res/{values,raw}). # @@ -193,16 +187,15 @@ t = ('android_apks', GENERATED_FILES += [t] GENERATED_FILES[t].force = True GENERATED_FILES[t].script = '/mobile/android/gradle.py:assemble_app' GENERATED_FILES[t].inputs += [ '!AndroidManifest.xml', '!generated/preprocessed/org/mozilla/gecko/AdjustConstants.java', '!generated/preprocessed/org/mozilla/gecko/AppConstants.java', - '!generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java', '!generated/preprocessed/org/mozilla/gecko/MmaConstants.java', # These all depend on AB_CD, which isn't captured in this definition. Due # to subtle RecursiveMake details, everything works out. In the future we # can try to express the APKs themselves as LOCALIZED_GENERATED_FILES. '!res/raw/suggestedsites.json', '!res/values/strings.xml', ]
--- a/mobile/android/components/SessionStore.js +++ b/mobile/android/components/SessionStore.js @@ -1278,18 +1278,17 @@ SessionStore.prototype = { let currentURI = aWindow.BrowserApp.selectedBrowser.currentURI; // if the current URI contains a username/password, remove it try { currentURI = currentURI.mutate() .setUserPass("") .finalize(); } catch (ex) { } // ignore failures on about: URIs - Services.appinfo.annotateCrashReport(Services.appinfo.URL, - currentURI.spec); + Services.appinfo.annotateCrashReport("URL", currentURI.spec); } catch (ex) { // don't make noise when crashreporter is built but not enabled if (ex.result != Cr.NS_ERROR_NOT_INITIALIZED) { Cu.reportError("SessionStore:" + ex); } } },
--- a/mozglue/build/WindowsDllBlocklist.cpp +++ b/mozglue/build/WindowsDllBlocklist.cpp @@ -19,42 +19,50 @@ #include <io.h> #pragma warning( push ) #pragma warning( disable : 4275 4530 ) // See msvc-stl-wrapper.template.h #include <map> #pragma warning( pop ) #include "Authenticode.h" -#include "CrashAnnotations.h" #include "nsAutoPtr.h" #include "nsWindowsDllInterceptor.h" #include "mozilla/Sprintf.h" #include "mozilla/StackWalk_windows.h" #include "mozilla/UniquePtr.h" #include "mozilla/Vector.h" #include "mozilla/WindowsVersion.h" #include "nsWindowsHelpers.h" #include "WindowsDllBlocklist.h" #include "mozilla/AutoProfilerLabel.h" #include "mozilla/glue/WindowsDllServices.h" using namespace mozilla; -using CrashReporter::Annotation; -using CrashReporter::AnnotationToString; - #define DLL_BLOCKLIST_ENTRY(name, ...) \ { name, __VA_ARGS__ }, #define DLL_BLOCKLIST_STRING_TYPE const char* #include "mozilla/WindowsDllBlocklistDefs.h" // define this for very verbose dll load debug spew #undef DEBUG_very_verbose +static const char kBlockedDllsParameter[] = "BlockedDllList="; +static const int kBlockedDllsParameterLen = + sizeof(kBlockedDllsParameter) - 1; + +static const char kBlocklistInitFailedParameter[] = "BlocklistInitFailed=1\n"; +static const int kBlocklistInitFailedParameterLen = + sizeof(kBlocklistInitFailedParameter) - 1; + +static const char kUser32BeforeBlocklistParameter[] = "User32BeforeBlocklist=1\n"; +static const int kUser32BeforeBlocklistParameterLen = + sizeof(kUser32BeforeBlocklistParameter) - 1; + static uint32_t sInitFlags; static bool sBlocklistInitAttempted; static bool sBlocklistInitFailed; static bool sUser32BeforeBlocklist; // Duplicated from xpcom glue. Ideally this should be shared. void printf_stderr(const char *fmt, ...) @@ -767,40 +775,32 @@ DllBlocklist_Initialize(uint32_t aInitFl if (pProc) { gStartAddressesToBlock->append(pProc); } } #endif } static void -WriteAnnotation(HANDLE aFile, Annotation aAnnotation, const char* aValue, - DWORD* aNumBytes) -{ - const char* str = AnnotationToString(aAnnotation); - WriteFile(aFile, str, strlen(str), aNumBytes, nullptr); - WriteFile(aFile, "=", 1, aNumBytes, nullptr); - WriteFile(aFile, aValue, strlen(aValue), aNumBytes, nullptr); -} - -static void InternalWriteNotes(HANDLE file) { DWORD nBytes; - WriteAnnotation(file, Annotation::BlockedDllList, "", &nBytes); + WriteFile(file, kBlockedDllsParameter, kBlockedDllsParameterLen, &nBytes, nullptr); DllBlockSet::Write(file); WriteFile(file, "\n", 1, &nBytes, nullptr); if (sBlocklistInitFailed) { - WriteAnnotation(file, Annotation::BlocklistInitFailed, "1\n", &nBytes); + WriteFile(file, kBlocklistInitFailedParameter, + kBlocklistInitFailedParameterLen, &nBytes, nullptr); } if (sUser32BeforeBlocklist) { - WriteAnnotation(file, Annotation::User32BeforeBlocklist, "1\n", &nBytes); + WriteFile(file, kUser32BeforeBlocklistParameter, + kUser32BeforeBlocklistParameterLen, &nBytes, nullptr); } } using WriterFn = void (*)(HANDLE); static WriterFn gWriterFn = &InternalWriteNotes; static void GetNativeNtBlockSetWriter()
--- a/netwerk/ipc/NeckoMessageUtils.h +++ b/netwerk/ipc/NeckoMessageUtils.h @@ -102,18 +102,17 @@ struct ParamTraits<mozilla::net::NetAddr // Train's already off the rails: let's get a stack trace at least... MOZ_CRASH("Error: please post stack trace to " "https://bugzilla.mozilla.org/show_bug.cgi?id=661158"); aMsg->WriteBytes(aParam.local.path, sizeof(aParam.local.path)); #endif } else { if (XRE_IsParentProcess()) { nsPrintfCString msg("%d", aParam.raw.family); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::UnknownNetAddrSocketFamily, msg); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Unknown NetAddr socket family"), msg); } MOZ_CRASH("Unknown socket family"); } } static bool Read(const Message* aMsg, PickleIterator* aIter, mozilla::net::NetAddr* aResult) {
--- a/storage/mozStorageService.cpp +++ b/storage/mozStorageService.cpp @@ -791,17 +791,17 @@ Service::Observe(nsISupports *, const ch if (gShutdownChecks == SCM_CRASH) { nsTArray<RefPtr<Connection> > connections; getConnections(connections); for (uint32_t i = 0, n = connections.Length(); i < n; i++) { if (!connections[i]->isClosed()) { // getFilename is only the leaf name for the database file, // so it shouldn't contain privacy-sensitive information. CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::StorageConnectionNotClosed, + NS_LITERAL_CSTRING("StorageConnectionNotClosed"), connections[i]->getFilename()); #ifdef DEBUG printf_stderr("Storage connection not closed: %s", connections[i]->getFilename().get()); #endif MOZ_CRASH(); } }
--- a/toolkit/components/asyncshutdown/AsyncShutdown.jsm +++ b/toolkit/components/asyncshutdown/AsyncShutdown.jsm @@ -40,21 +40,31 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://gre/modules/Services.jsm", this); ChromeUtils.defineModuleGetter(this, "PromiseUtils", "resource://gre/modules/PromiseUtils.jsm"); ChromeUtils.defineModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); -XPCOMUtils.defineLazyModuleGetters(this, { - CrashReporter: "resource://gre/modules/CrashReporter.jsm", -}); XPCOMUtils.defineLazyServiceGetter(this, "gDebug", "@mozilla.org/xpcom/debug;1", "nsIDebug2"); +Object.defineProperty(this, "gCrashReporter", { + get() { + delete this.gCrashReporter; + try { + let reporter = Cc["@mozilla.org/xre/app-info;1"]. + getService(Ci.nsICrashReporter); + return this.gCrashReporter = reporter; + } catch (ex) { + return this.gCrashReporter = null; + } + }, + configurable: true +}); // `true` if this is a content process, `false` otherwise. // It would be nicer to go through `Services.appinfo`, but some tests need to be // able to replace that field with a custom implementation before it is first // called. // eslint-disable-next-line mozilla/use-services const isContent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT; @@ -929,23 +939,22 @@ Barrier.prototype = Object.freeze({ // helps automatically sort oranges. let msg = "AsyncShutdown timeout in " + topic + " Conditions: " + JSON.stringify(state) + " At least one completion condition failed to complete" + " within a reasonable amount of time. Causing a crash to" + " ensure that we do not leave the user with an unresponsive" + " process draining resources."; fatalerr(msg); - if (CrashReporter.enabled) { + if (gCrashReporter && gCrashReporter.enabled) { let data = { phase: topic, conditions: state }; - CrashReporter.addAnnotation( - CrashReporter.annotations.AsyncShutdownTimeout, + gCrashReporter.annotateCrashReport("AsyncShutdownTimeout", JSON.stringify(data)); } else { warn("No crash reporter available"); } // To help sorting out bugs, we want to make sure that the // call to nsIDebug2.abort points to a guilty client, rather // than to AsyncShutdown itself. We pick a client that is
--- a/toolkit/components/crashes/CrashManager.jsm +++ b/toolkit/components/crashes/CrashManager.jsm @@ -216,16 +216,54 @@ this.CrashManager.prototype = Object.fre // The following are return codes for individual event file processing. // File processed OK. EVENT_FILE_SUCCESS: "ok", // The event appears to be malformed. EVENT_FILE_ERROR_MALFORMED: "malformed", // The type of event is unknown. EVENT_FILE_ERROR_UNKNOWN_EVENT: "unknown-event", + // A whitelist of crash annotations which do not contain sensitive data + // and are saved in the crash record and sent with Firefox Health Report. + ANNOTATION_WHITELIST: [ + "AsyncShutdownTimeout", + "BuildID", + "ipc_channel_error", + "LowCommitSpaceEvents", + "ProductID", + "ProductName", + "ReleaseChannel", + "RemoteType", + "SecondsSinceLastCrash", + "ShutdownProgress", + "StartupCrash", + "TelemetryEnvironment", + "Version", + // The following entries are not normal annotations that can be found in + // the .extra file but are included in the crash record/FHR: + "AvailablePageFile", + "AvailablePhysicalMemory", + "AvailableVirtualMemory", + "BlockedDllList", + "BlocklistInitFailed", + "ContainsMemoryReport", + "CrashTime", + "EventLoopNestingLevel", + "IsGarbageCollecting", + "MozCrashReason", + "OOMAllocationSize", + "SystemMemoryUsePercentage", + "TextureUsage", + "TotalPageFile", + "TotalPhysicalMemory", + "TotalVirtualMemory", + "UptimeTS", + "User32BeforeBlocklist", + ], + /** * Obtain a list of all dumps pending upload. * * The returned value is a promise that resolves to an array of objects * on success. Each element in the array has the following properties: * * id (string) * The ID of the crash (a UUID). @@ -594,26 +632,20 @@ this.CrashManager.prototype = Object.fre let payload = data.substring(start); return this._handleEventFilePayload(store, entry, type, date, payload); })(); }, _filterAnnotations(annotations) { let filteredAnnotations = {}; - let crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"] - .getService(Ci.nsICrashReporter); for (let line in annotations) { - try { - if (crashReporter.isAnnotationWhitelistedForPing(line)) { - filteredAnnotations[line] = annotations[line]; - } - } catch (e) { - // Silently drop unknown annotations + if (this.ANNOTATION_WHITELIST.includes(line)) { + filteredAnnotations[line] = annotations[line]; } } return filteredAnnotations; }, _sendCrashPing(crashId, type, date, metadata = {}) { // If we have a saved environment, use it. Otherwise report
--- a/toolkit/components/crashes/tests/xpcshell/crash.extra +++ b/toolkit/components/crashes/tests/xpcshell/crash.extra @@ -3,16 +3,17 @@ TelemetryEnvironment={"EscapedField":"Es EMCheckCompatibility=true ProductName=Firefox ContentSandboxCapabilities=119 TelemetryClientId= Vendor=Mozilla InstallTime=1000000000 Theme=classic/1.0 ReleaseChannel=default +AddonsShouldHaveBlockedE10s=1 ServerURL=https://crash-reports.mozilla.com SafeMode=0 ContentSandboxCapable=1 useragent_locale=en-US Version=55.0a1 BuildID=20170512114708 ProductID={ec8030f7-c20a-464f-9b0e-13a3a9e97384} TelemetryServerURL=
--- a/toolkit/components/gfx/SanityTest.js +++ b/toolkit/components/gfx/SanityTest.js @@ -1,15 +1,14 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const FRAME_SCRIPT_URL = "chrome://gfxsanity/content/gfxFrameScript.js"; const PAGE_WIDTH = 160; const PAGE_HEIGHT = 234; @@ -68,16 +67,26 @@ function reportResult(val) { Services.prefs.savePrefFile(null); } function reportTestReason(val) { let histogram = Services.telemetry.getHistogramById("GRAPHICS_SANITY_TEST_REASON"); histogram.add(val); } +function annotateCrashReport(value) { + try { + // "1" if we're annotating the crash report, "" to remove the annotation. + var crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"]. + getService(Ci.nsICrashReporter); + crashReporter.annotateCrashReport("GraphicsSanityTest", value ? "1" : ""); + } catch (e) { + } +} + function setTimeout(aMs, aCallback) { var timer = Cc["@mozilla.org/timer;1"]. createInstance(Ci.nsITimer); timer.initWithCallback(aCallback, aMs, Ci.nsITimer.TYPE_ONE_SHOT); } function takeWindowSnapshot(win, ctx) { // TODO: drawWindow reads back from the gpu's backbuffer, which won't catch issues with presenting @@ -226,18 +235,19 @@ var listener = { // We don't have a MessageManager if onWindowLoaded never fired. this.messages.forEach((msgName) => { this.mm.removeMessageListener(msgName, this); }); this.mm = null; } - CrashReporter.removeAnnotation( - CrashReporter.annotations.GraphicsSanityTest); + // Remove the annotation after we've cleaned everything up, to catch any + // incidental crashes from having performed the sanity test. + annotateCrashReport(false); } }; function SanityTest() {} SanityTest.prototype = { classID: Components.ID("{f3a8ca4d-4c83-456b-aee2-6a2cbf11e9bd}"), QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), @@ -315,18 +325,17 @@ SanityTest.prototype = { // profile-after-change fires only at startup, so we won't need // to use the listener again. let tester = listener; listener = null; if (!this.shouldRunTest()) return; - CrashReporter.addAnnotation( - CrashReporter.annotations.GraphicsSanityTest, "1"); + annotateCrashReport(true); // Open a tiny window to render our test page, and notify us when it's loaded var sanityTest = Services.ww.openWindow(null, "chrome://gfxsanity/content/sanityparent.html", "Test Page", "width=" + PAGE_WIDTH + ",height=" + PAGE_HEIGHT + ",chrome,titlebar=0,scrollbars=0,popup=1", null);
--- a/toolkit/components/telemetry/TelemetrySend.jsm +++ b/toolkit/components/telemetry/TelemetrySend.jsm @@ -13,17 +13,16 @@ var EXPORTED_SYMBOLS = [ "TelemetrySend", ]; ChromeUtils.import("resource://gre/modules/AppConstants.jsm", this); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://gre/modules/ClientID.jsm"); -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm", this); ChromeUtils.import("resource://gre/modules/Log.jsm", this); ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm"); ChromeUtils.import("resource://gre/modules/ServiceRequest.jsm", this); ChromeUtils.import("resource://gre/modules/Services.jsm", this); ChromeUtils.import("resource://gre/modules/TelemetryUtils.jsm", this); ChromeUtils.import("resource://gre/modules/Timer.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryStorage", @@ -677,30 +676,31 @@ var TelemetrySendImpl = { /** * Triggers the crash report annotations depending on the current * configuration. This communicates to the crash reporter if it can send a * crash ping or not. This method can be called safely before setup() has * been called. */ _annotateCrashReport() { try { - let clientId = ClientID.getCachedClientID(); - let server = this._server || Services.prefs.getStringPref(TelemetryUtils.Preferences.Server, undefined); + const cr = Cc["@mozilla.org/toolkit/crash-reporter;1"]; + if (cr) { + const crs = cr.getService(Ci.nsICrashReporter); + + let clientId = ClientID.getCachedClientID(); + let server = this._server || Services.prefs.getStringPref(TelemetryUtils.Preferences.Server, undefined); - if (!this.sendingEnabled() || !TelemetryReportingPolicy.canUpload()) { - // If we cannot send pings then clear the crash annotations - CrashReporter.removeAnnotation( - CrashReporter.annotations.TelemetryClientId); - CrashReporter.removeAnnotation( - CrashReporter.annotations.TelemetryServerURL); - } else { - CrashReporter.addAnnotation( - CrashReporter.annotations.TelemetryClientId, clientId); - CrashReporter.addAnnotation( - CrashReporter.annotations.TelemetryServerURL, server); + if (!this.sendingEnabled() || !TelemetryReportingPolicy.canUpload()) { + // If we cannot send pings then clear the crash annotations + crs.annotateCrashReport("TelemetryClientId", ""); + crs.annotateCrashReport("TelemetryServerURL", ""); + } else { + crs.annotateCrashReport("TelemetryClientId", clientId); + crs.annotateCrashReport("TelemetryServerURL", server); + } } } catch (e) { // Ignore errors when crash reporting is disabled } }, /** * Discard old pings from the pending pings and detect overdue ones.
--- a/toolkit/components/telemetry/TelemetryStartup.js +++ b/toolkit/components/telemetry/TelemetryStartup.js @@ -1,16 +1,15 @@ /* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm", this); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryController", "resource://gre/modules/TelemetryController.jsm"); ChromeUtils.defineModuleGetter(this, "TelemetryEnvironment", "resource://gre/modules/TelemetryEnvironment.jsm"); /** @@ -31,17 +30,19 @@ TelemetryStartup.prototype.observe = fun annotateEnvironment(); TelemetryEnvironment.registerChangeListener("CrashAnnotator", annotateEnvironment); TelemetryEnvironment.onInitialized().then(() => annotateEnvironment()); } }; function annotateEnvironment() { try { - let env = JSON.stringify(TelemetryEnvironment.currentEnvironment); - CrashReporter.addAnnotation(CrashReporter.annotations.TelemetryEnvironment, - env); + let cr = Cc["@mozilla.org/toolkit/crash-reporter;1"]; + if (cr) { + let env = JSON.stringify(TelemetryEnvironment.currentEnvironment); + cr.getService(Ci.nsICrashReporter).annotateCrashReport("TelemetryEnvironment", env); + } } catch (e) { // crash reporting not built or disabled? Ignore errors } } this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelemetryStartup]);
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js @@ -4,28 +4,26 @@ // This tests the public Telemetry API for submitting pings. "use strict"; ChromeUtils.import("resource://gre/modules/TelemetryController.jsm", this); ChromeUtils.import("resource://testing-common/ContentTaskUtils.jsm", this); ChromeUtils.import("resource://testing-common/MockRegistrar.jsm", this); -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm", this); ChromeUtils.import("resource://gre/modules/TelemetrySession.jsm", this); +ChromeUtils.import("resource://gre/modules/TelemetrySend.jsm", this); ChromeUtils.import("resource://gre/modules/TelemetryStorage.jsm", this); ChromeUtils.import("resource://gre/modules/TelemetryUtils.jsm", this); ChromeUtils.import("resource://gre/modules/Services.jsm", this); ChromeUtils.import("resource://gre/modules/osfile.jsm", this); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this); -ChromeUtils.defineModuleGetter(this, "TelemetrySend", - "resource://gre/modules/TelemetrySend.jsm"); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", "resource://gre/modules/TelemetryHealthPing.jsm"); XPCOMUtils.defineLazyServiceGetter(Services, "cookies", "@mozilla.org/cookieService;1", "nsICookieService"); const MS_IN_A_MINUTE = 60 * 1000; function countPingTypes(pings) { @@ -602,101 +600,73 @@ add_task(async function test_measurePing Assert.equal(histogramValueCount(histSuccessPingSize.snapshot()), 2, "Should have recorded 2 successful ping into histogram."); Assert.equal(histogramValueCount(histFailedPingSize.snapshot()), 1, "Should have recorded 1 failed ping into histogram."); }); add_task(async function test_pref_observer() { // This test requires the presence of the crash reporter component. - if (!AppConstants.MOZ_CRASHREPORTER) { + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + if (!registrar.isContractIDRegistered("@mozilla.org/toolkit/crash-reporter;1")) { return; } - // Mock the crash reporter wrapper so that we can inspect the annotations - var MockCrashReporter = { - addAnnotation(annotation, value) { - if (!this.keys.delete(annotation)) { - let string = Object.keys(CrashReporter.annotations) - .find(key => key === annotation); - if (this.reject) { - this.reject( - Error(`Crash report annotation with unexpected key: "${string}".`)); - } - } - - if (this.expectedValue && value == "") { - if (this.reject) { - this.reject(Error("Crash report annotation without expected value.")); - } - } - - if (this.keys.size == 0) { - if (this.resolve) { - this.resolve(); - } - } - }, - removeAnnotation(annotation) { - if (!this.keys.delete(annotation)) { - let string = Object.keys(CrashReporter.annotations) - .find(key => key === annotation); - if (this.reject) { - this.reject( - Error(`Crash report annotation with unexpected key: "${string}".`)); - } - } - - if (this.keys.size == 0) { - if (this.resolve) { - this.resolve(); - } - } - }, - annotations: Object.assign({}, CrashReporter.annotations), - keys: null, - expectedValue: false, - resolve: null, - reject: null, - }; - - let ts_scope = ChromeUtils.import("resource://gre/modules/TelemetrySend.jsm", - {}); - - ts_scope.CrashReporter = MockCrashReporter; - registerCleanupFunction(function() { - ts_scope.CrashReporter = CrashReporter; - }); - - function waitAnnotateCrashReport(expectedValue, trigger) { - MockCrashReporter.expectedValue = expectedValue; - MockCrashReporter.keys = new Set([ - CrashReporter.annotations.TelemetryClientId, - CrashReporter.annotations.TelemetryServerURL - ]); - - return new Promise(function(resolve, reject) { - MockCrashReporter.resolve = resolve; - MockCrashReporter.reject = reject; - trigger(); - }); - } - await TelemetrySend.setup(true); const IS_UNIFIED_TELEMETRY = Services.prefs.getBoolPref(TelemetryUtils.Preferences.Unified, false); let origTelemetryEnabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.TelemetryEnabled); let origFhrUploadEnabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled); if (!IS_UNIFIED_TELEMETRY) { Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, true); } Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, true); + function waitAnnotateCrashReport(expectedValue, trigger) { + return new Promise(function(resolve, reject) { + let keys = new Set(["TelemetryClientId", "TelemetryServerURL"]); + + let crs = { + QueryInterface: ChromeUtils.generateQI([Ci.nsICrashReporter]), + annotateCrashReport(key, value) { + if (!keys.delete(key)) { + MockRegistrar.unregister(gMockCrs); + reject(Error(`Crash report annotation with unexpected key: "${key}".`)); + } + + if (expectedValue && value == "") { + MockRegistrar.unregister(gMockCrs); + reject(Error("Crash report annotation without expected value.")); + } + + if (!expectedValue && value != "") { + MockRegistrar.unregister(gMockCrs); + reject(Error(`Crash report annotation ("${key}") with unexpected value: "${value}".`)); + } + + if (keys.size == 0) { + MockRegistrar.unregister(gMockCrs); + resolve(); + } + }, + UpdateCrashEventsDir() { + }, + }; + + let gMockCrs = MockRegistrar.register("@mozilla.org/toolkit/crash-reporter;1", crs); + registerCleanupFunction(function() { + MockRegistrar.unregister(gMockCrs); + }); + + trigger(); + }); + } + await waitAnnotateCrashReport(!IS_UNIFIED_TELEMETRY, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, false)); await waitAnnotateCrashReport(true, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, true)); if (!IS_UNIFIED_TELEMETRY) { Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, origTelemetryEnabled); } Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, origFhrUploadEnabled);
--- a/toolkit/components/terminator/nsTerminator.cpp +++ b/toolkit/components/terminator/nsTerminator.cpp @@ -598,18 +598,18 @@ nsTerminator::UpdateTelemetry() } void nsTerminator::UpdateCrashReport(const char* aTopic) { // In case of crash, we wish to know where in shutdown we are nsAutoCString report(aTopic); - Unused << CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ShutdownProgress, report); + Unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"), + report); } void XPCOMShutdownNotified() { MOZ_DIAGNOSTIC_ASSERT(sShutdownNotified == false); sShutdownNotified = true; }
deleted file mode 100644 --- a/toolkit/crashreporter/CrashAnnotations.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CrashAnnotations.h" - -#include <algorithm> -#include <cstring> -#include <iterator> - -using std::begin; -using std::end; -using std::find_if; - -namespace CrashReporter { - -bool -AnnotationFromString(Annotation& aResult, const char* aValue) -{ - auto elem = find_if( - begin(kAnnotationStrings), - end(kAnnotationStrings), - [&aValue](const char* aString) { - return strcmp(aString, aValue) == 0; - } - ); - - if (elem == end(kAnnotationStrings)) { - return false; - } - - aResult = static_cast<Annotation>(elem - begin(kAnnotationStrings)); - return true; -} - -bool -IsAnnotationWhitelistedForPing(Annotation aAnnotation) { - auto elem = find_if( - begin(kCrashPingWhitelist), - end(kCrashPingWhitelist), - [&aAnnotation](Annotation aElement) { - return aElement == aAnnotation; - } - ); - - return elem != end(kCrashPingWhitelist); -} - -bool -IsAnnotationBlacklistedForContent(Annotation aAnnotation) -{ - auto elem = find_if( - begin(kContentProcessBlacklist), - end(kContentProcessBlacklist), - [&aAnnotation](Annotation aElement) { - return aElement == aAnnotation; - } - ); - - return elem != end(kContentProcessBlacklist); -} - -} // namespace CrashReporter
deleted file mode 100644 --- a/toolkit/crashreporter/CrashAnnotations.h.in +++ /dev/null @@ -1,76 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef CrashAnnotations_h -#define CrashAnnotations_h - -#include <cstdint> - -namespace CrashReporter { - -// Typed enum representing all crash annotations -enum class Annotation : uint32_t { -${enum} -}; - -// Stringified crash annotation names -const char* const kAnnotationStrings[] = { -${strings} -}; - -// Whitelist of crash annotations that can be included in a crash ping -const Annotation kCrashPingWhitelist[] = { -${whitelist} -}; - -// Blacklist of crash annotations that shouldn't be read from a content process -const Annotation kContentProcessBlacklist[] = { -${blacklist} -}; - -/** - * Return the string representation of a crash annotation. - * - * @param aAnnotation a crash annotation - * @returns A constant string holding the annotation name - */ -static inline const char* -AnnotationToString(Annotation aAnnotation) { - return kAnnotationStrings[static_cast<uint32_t>(aAnnotation)]; -} - -/** - * Converts a string to its corresponding crash annotation. - * - * @param aResult a reference where the annotation will be stored - * @param aValue the string to be converted - * @return true if the string was successfully converted, false if it did not - * correspond to any known annotation - */ -bool AnnotationFromString(Annotation& aResult, const char* aValue); - -/** - * Checks if the given crash annotation is whitelisted for inclusion in the - * crash ping. - * - * @param aAnnotation the crash annotation to be checked - * @return true if the annotation can be included in the crash ping, false - * otherwise - */ -bool IsAnnotationWhitelistedForPing(Annotation aAnnotation); - -/** - * Checks if the given crash annotation needs to be filtered out when reading - * a content process crash annotations. Blacklisted annotations will be - * replaced with ones provided by the parent process. - * - * @param aAnnotation the crash annotation to be checked - * @return true if the annotation needs to be filtered out when reading - * annotations provided by a content process, false otherwise - */ -bool IsAnnotationBlacklistedForContent(Annotation aAnnotation); - -} // namespace CrashReporter - -#endif // CrashAnnotations_h
deleted file mode 100644 --- a/toolkit/crashreporter/CrashAnnotations.yaml +++ /dev/null @@ -1,776 +0,0 @@ -# This lists all the available crash annotations. -# -# Mandatory fields for each entry are: -# - description: A string describing the annotation -# - type: the annotation type, currently `string`, `integer` or `boolean`. -# The latter are stringified to `1` for true and `0` for false. -# -# Additionally a field can have the following optional fields: -# - altname: A string that will be used when writing out the annotation to the -# .extra file instead of the annotation name -# - ping: A boolean that indicates whether the annotation is whitelisted for -# going into the crash ping, if not specified this defaults to false -# - content: A boolean that indicates whether the field will be included in -# subprocess reports, if not specified this defaults to true - -A11yHandlerRegistered: - description: > - Set to "true" if the accessibility handler is registered, "false" otherwise. - type: string - -AbortMessage: - description: > - Message passed to NS_DebugBreak(). - type: string - -Accessibility: - description: > - Set to "Active" by the accessibility service when it is active. - type: string - -AccessibilityClient: - description: > - Accessibility client ID. - type: string - -AccessibilityInProcClient: - description: > - Hexadecimal mask of in-process accessibility consumers, see - accessible/windows/msaa/Compatibility.h for the mappings. - type: string - -ActualStreamLen: - description: > - Actual length of an IPC proxy stream. - type: integer - -AdapterDeviceID: - description: > - Graphics adapter name. - type: string - -AdapterDriverVersion: - description: > - Graphics adapter driver version. - type: string - -AdapterSubsysID: - description: > - Graphics adapter subsystem ID. - type: string - -AdapterVendorID: - description: > - Graphics adapter vendor name. - type: string - -additional_minidumps: - description: > - Comma separated list of additional minidumps for this crash, each element - in the list represent the suffix used in the dump filename. E.g. the - "browser" entry for crash fa909194-737b-4b93-b8da-da110ac785e0 implies the - existence of the fa909194-737b-4b93-b8da-da110ac785e0-browser.dmp file. - type: string - -Addons: - description: > - List of currently enabled add-ons. - type: string - altname: Add-ons - -AppInitDLLs: - description: > - List of DLLs loaded when launching any application on Windows, this - reflects the contents of the AppInit_DLLs registry key. - type: string - -AsyncShutdownModule: - description: > - Holds the contents of the AsyncShutdown.js script - type: string - -AsyncShutdownTimeout: - description: > - This annotation is present if a shutdown blocker was not released in time - and the browser was crashed instead of waiting for shutdown to finish. The - condition that caused the hang is contained in the annotation. - type: string - ping: true - -AvailablePageFile: - description: > - Windows-only, maximum amount of memory that can be committed. This - annotation is populated with the contents of the MEMORYSTATUSEX's structure - ullAvailPageFile field. - type: string - ping: true - -AvailablePhysicalMemory: - description: > - Windows-only, amount of free physical memory in bytes. This annotation - is populated with the contents of the MEMORYSTATUSEX's structure - ullAvailPhys field. - type: string - ping: true - -AvailableVirtualMemory: - description: > - Windows-only, amount of free virtual memory in bytes. This annotation is - populated with the contents of the MEMORYSTATUSEX's structure - ullAvailVirtual field. - type: string - ping: true - -BIOS_Manufacturer: - description: > - Name of the BIOS manufacturer. - type: string - -BlockedDllList: - description: > - Comma-separated list of blocked DLLS, Windows-only - type: string - ping: true - -BlocklistInitFailed: - description: > - Set to 1 if the DLL blocklist could not be initialized. - type: boolean - ping: true - -BreakpadReserveAddress: - description: > - Address of the buffer reserved by Breakpad. - type: string - -BreakpadReserveSize: - description: > - Size of the buffer reserved by Breakpad. - type: string - -BuildID: - description: > - Application build ID, the format is YYYYMMDDHHMMSS. - type: string - ping: true - -ClassRegistrationInfoChild: - description: > - Microsoft COM class registration annotation for the child process. - type: string - -ClassRegistrationInfoParent: - description: > - Microsoft COM class registration annotation for the parent process. - type: string - -CoMarshalInterfaceFailure: - description: > - Annotation describing the error returned by trying to marshal an object - via CoMarshalInterface during the creation of an IPC proxy stream. - type: string - -ContainsMemoryReport: - description: > - Indicates that the crash dump contains a memory report. - type: boolean - ping: true - -ContentSandboxCapabilities: - description: > - List of capabilities of the content process sandbox. - type: string - -ContentSandboxEnabled: - description: > - Set to 1 when content process sandboxing is enabled. - type: boolean - -ContentSandboxCapable: - description: > - Set to 1 if the client is capable of content sandboxing. - type: boolean - -ContentSandboxLevel: - description: > - Content sandbox level. - type: integer - -CoUnmarshalInterfaceResult: - description: > - Annotation describing the error returned by trying to unmarshal an object - via CoUnmarshalInterface during the creation of an IPC proxy stream. - type: integer - -CPUMicrocodeVersion: - description: > - Version of the CPU microcode. - type: string - -CpuUsageFlashProcess1: - description: > - CPU usage of the first Adobe Flash plugin process. - type: string - -CpuUsageFlashProcess2: - description: > - CPU usage of the second Adobe Flash plugin process. - type: string - -CrashAddressLikelyWrong: - description: > - Set to 1 if signal handling is broken, in which case the crash address is - likely to be wrong. - type: boolean - -CrashTime: - description: > - Crash time in seconds since the Epoch. - type: string - ping: true - -CreateStreamOnHGlobalFailure: - description: > - Set when failing to obtain a global memory handle during the creation of an - IPC proxy stream. - type: string - -CycleCollector: - description: > - Reason why the cycle collector crashed. - type: string - -DeviceResetReason: - description: > - Reason why a DirectX device has been reset, Windows only. - type: string - -DOMIPCEnabled: - description: > - Set to 1 when a tab is running in a content process - type: boolean - -EMCheckCompatibility: - description: > - Set to 1 if add-on compatibility checking is enabled. - type: boolean - -EventLoopNestingLevel: - description: > - Present only if higher than 0, indicates that we're running in a nested - event loop and indicates the nesting level. - type: integer - ping: true - -ExpectedStreamLen: - description: > - Expected length of an IPC proxy stream. - type: integer - -FlashProcessDump: - description: > - Type of process the flash plugin is running in, can be either "Broker" or - "Sandbox". - type: string - -FramePoisonBase: - description: > - Base pointer of the memory area used for the poison value we place in freed - memory. - type: string - content: false - -FramePoisonSize: - description: > - Size of the memory area used for the poison value we place in freed - memory. - type: integer - content: false - -GetHGlobalFromStreamFailure: - description: > - Error returned when invoking GetHGlobalFromStreamFailure() during the - creation of an IPC stream proxy. - type: string - -GMPLibraryPath: - description: > - Holds the path to the GMP plugin library. - type: string - -GMPPlugin: - description: > - Set to 1 if the GMP plugin is enabled. - type: boolean - -GPUProcessLaunchCount: - description: > - Number of times the GPU process was launched. - type: integer - -GPUProcessStatus: - description: > - Status of the GPU process, can be set to "Running" or "Destroyed" - type: string - -GraphicsCriticalError: - description: > - Information of a critical error that occurred within the graphics code. - type: string - -GraphicsSanityTest: - description: > - Annotation used in tests. - type: string - -GraphicsStartupTest: - description: > - Set to 1 by the graphics driver crash guard when it's activated. - type: boolean - -HangMonitorDescription: - description: > - Name of the hang monitor that generated the crash. - type: string - -HasDeviceTouchScreen: - description: > - Set to 1 if the device had a touch-screen, this only applies to Firefox - desktop as on mobile devices we assume a touch-screen is always present. - type: boolean - -IAccessibleConfig: - description: > - Set when something is seriously wrong with the IAccessible configuration in - the computer's registry. The value is always set to "NoSystemTypeLibOrPS" - type: string - -InstallTime: - description: > - The time when Firefox was installed expressed as seconds since the Epoch - type: integer - -InterfaceRegistrationInfoChild: - description: > - Microsoft COM interface registration annotation for the child process. - type: string - -InterfaceRegistrationInfoParent: - description: > - Microsoft COM interface registration annotation for the parent process. - type: string - -ipc_channel_error: - description: > - Set before a content process crashes because of an IPC channel error, holds - a description of the error. - type: string - ping: true - -IpcCreateEndpointsNsresult: - description: > - errno value retrieved after failing to create an IPC transport object. - type: integer - -IpcCreatePipeCloExecErrno: - description: > - errno value retrieved after failing to set the O_CLOEXEC flag on a pipe - used for IPC. - type: integer - -IpcCreatePipeFcntlErrno: - description: > - errno value retrieved after a call to fcntl() on a pipe used for IPC failed. - type: integer - -IpcCreatePipeSocketPairErrno: - description: > - errno value retrieved after a socketpair() call failed while creating an IPC - transport object. - type: integer - -IpcCreateTransportDupErrno: - description: > - errno value retrieved after a dup() call failed while creating an IPC - transport object. - type: integer - -IPCFatalErrorMsg: - description: > - Describes a fatal error that occurred during IPC operation. - type: string - -IPCFatalErrorProtocol: - description: > - Name of the protocol used by IPC when a fatal error occurred. - type: string - -IPCMessageName: - description: > - Name of the IPC message that caused a crash because it was too large. - type: string - -IPCMessageSize: - description: > - Size of the IPC message that caused a crash because it was too large. - type: integer - -IPCReadErrorReason: - description: > - Reason why reading an object via IPC failed. - type: string - -IPCShutdownState: - description: > - IPC shutdown state, can be set to either "RecvShutdown" or - "SendFinishShutdown" by a content process while it's shutting down. - type: string - -IPCSystemError: - description: > - Description of the last system error that occurred during IPC operation. - type: string - -IPCTransportFailureReason: - description: > - Reason why creating an IPC channel failed. - type: string - -IsGarbageCollecting: - description: > - If true then the JavaScript garbage collector was running when the crash - occurred. - type: boolean - ping: true - -JavaStackTrace: - description: > - Java stack trace, only present on Firefox for Android if we encounter an - uncaught Java exception. - type: string - -JSLargeAllocationFailure: - description: > - A large allocation couldn't be satisfied, check the JSOutOfMemory - description for the possible values of this annotation. - type: string - -JSOutOfMemory: - description: > - A small allocation couldn't be satisfied, the annotation may contain the - "Reporting", "Reported" or "Recovered" value. The first one means that - we crashed while responding to the OOM condition (possibly while running a - memory-pressure observers), the second that we crashed after having tried to - free some memory, and the last that the GC had managed to free enough memory - to satisfy the allocation. - type: string - -LowCommitSpaceEvents: - description: > - Number of times the available memory tracker has detected a that - commit-space was running low. This is a Windows-specific annotation. - type: integer - ping: true - -MarshalActCtxManifestPath: - description: > - Proxy stream marshalling current activation context manifest path. - type: string - -MozCrashReason: - description: > - Plaintext description of why Firefox crashed, this is usually set by - assertions and the like. - type: string - ping: true - -Notes: - description: > - Miscellaneous notes that can be appended to a crash. - type: string - -nsAsyncShutdownComponent: - description: > - Holds the contents of the nsAsyncShutdown.js script - type: string - -NumberOfProcessors: - description: > - Number of logical processors in the system. - type: integer - -OOMAllocationSize: - description: > - Size of the allocation that caused an out-of-memory condition. - type: string - ping: true - -PluginCpuUsage: - description: > - CPU usage of the plugin process. - type: string - -PluginFilename: - description: > - Plugin filename, only the process holding the plugin has this annotation. - type: string - -PluginHang: - description: > - The presence of this annotation indicates that this crash was generated in - response to a plugin hanging. - type: boolean - -PluginHangUIDuration: - description: > - Duration in milliseconds of the plugin hang that caused this crash. - type: integer - -PluginName: - description: > - Display name of a plugin, only the process holding the plugin has this - annotation. - type: string - -PluginVersion: - description: > - Version of a plugin, only the process holding the plugin has this - annotation. - type: string - -ProcessType: - description: > - Type of the process that crashed, can hold the values "content", "plugin" or - "gpu" currently. - type: string - -ProductName: - description: > - Application name (e.g. Firefox). - type: string - ping: true - -ProductID: - description: > - Application UUID (e.g. ec8030f7-c20a-464f-9b0e-13a3a9e97384). - type: string - ping: true - -ProxyStreamSize: - description: > - Size of an IPC proxy stream. - type: integer - -ProxyStreamSizeFrom: - description: > - Describes how the size of a proxy stream was obtained. It can be set to - either Stream::Stat or GlobalSize. - type: string - -ProxyStreamUnmarshalStatus: - description: > - Status of the proxy stream unmarshalling, see ipc/mscom/ProxyStream.cpp for - the various value this annotation can take. - type: string - -ProxyStreamValid: - description: > - Set to "false" when encountering an invalid IPC proxy stream. - type: string - -ReleaseChannel: - description: > - Application release channel (e.g. default, beta, ...) - type: string - ping: true - -RemoteType: - description: > - Type of the content process, can be set to "web", "file" or "extension". - type: string - ping: true - -SafeMode: - description: > - Set to 1 if the browser was started in safe mode. - type: boolean - -SecondsSinceLastCrash: - description: > - Time in seconds since the last crash occurred. - type: string - ping: true - -ServerURL: - description: > - URL used to post the crash report. - type: string - -SheetLoadFailure: - description: > - Set when failing to load a built-in style sheet. This can contain a - potentially very large amount of diagnostic information. - type: string - -ShutdownProgress: - description: > - Shutdown step at which the browser crashed, can be set to "quit-application", - "profile-change-teardown", "profile-before-change", "xpcom-will-shutdown" or - "xpcom-shutdown". - type: string - ping: true - -StartupCrash: - description: > - If set to 1 then this crash occurred during startup. - type: boolean - content: false - ping: true - -StartupTime: - description: > - The time when Firefox was launched expressed in seconds since the Epoch. - type: integer - content: false - -StatFailure: - description: > - Error returned when invoking IStream's Stat function during the creation - of an IPC proxy stream. - type: string - -StorageConnectionNotClosed: - description: > - This annotation is added when a mozStorage connection has not been properly - closed during shutdown. The annotation holds the filename of the database - associated with the connection. - type: string - -SystemMemoryUsePercentage: - description: > - Windows-only, percentage of physical memory in use. This annotation is - populated with the contents of the MEMORYSTATUSEX's structure dwMemoryLoad - field. - type: integer - ping: true - -TelemetryClientId: - description: > - Telemetry client ID. - type: string - -TelemetryEnvironment: - description: > - The telemetry environment in JSON format. - type: string - -TelemetryServerURL: - description: > - Telemetry server URL. Used to send main process crash pings directly from - the crashreporter client. - type: string - -TelemetrySessionId: - description: > - Telemetry session ID. - type: string - -TestKey: - description: > - Annotation used in tests. - type: string - -TestUnicode: - description: > - Annotation used in tests. - type: string - -TextureUsage: - description: > - Amount of memory in bytes consumed by textures. - type: string - ping: true - -ThreadIdNameMapping: - description: > - List of thread names with their corresponding thread IDs. - type: string - -TotalPageFile: - description: > - Windows-only, current committed memory limit. This annotation is - populated with the contents of the MEMORYSTATUSEX's structure - ullTotalPageFile field. - type: string - ping: true - -TotalPhysicalMemory: - description: > - Windows-only, amount of physical memory in bytes. This annotation is - populated with the contents of the MEMORYSTATUSEX's structure - ullTotalPhys field. - type: string - ping: true - -TotalVirtualMemory: - description: > - Windows-only, size of the virtual address space. This annotation is - populated with the contents of the MEMORYSTATUSEX's structure - ullTotalVirtual field. - type: string - ping: true - -UnknownNetAddrSocketFamily: - description: > - An unknown network address family was requested to Necko. The value is the - requested family number. - type: integer - -UnmarshalActCtx: - description: > - Proxy stream unmarshalling current activation context. - type: string - -UnmarshalActCtxManifestPath: - description: > - Proxy stream unmarshalling current activation context manifest path. - type: string - -UptimeTS: - description: > - Uptime in seconds. This annotation uses a string instead of an integer - because it has a fractional component. - type: string - ping: true - -URL: - description: > - URL being loaded. - type: string - content: false - -User32BeforeBlocklist: - description: > - Set to 1 if user32.dll was loaded before we could install the DLL blocklist. - type: boolean - ping: true - -useragent_locale: - description: > - User-agent locale. - type: string - -Vendor: - description: > - Application vendor (e.g. Mozilla). - type: string - -Version: - description: > - Product version. - type: string - -Winsock_LSP: - description: > - Information on winsock LSPs injected in our networking stack. - type: string
deleted file mode 100644 --- a/toolkit/crashreporter/CrashReporter.jsm.in +++ /dev/null @@ -1,45 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); -ChromeUtils.import("resource://gre/modules/Services.jsm"); - -var EXPORTED_SYMBOLS = [ - "CrashReporter" -]; - -var gCrashReporter = null; - -function getCrashReporter() { - if (!gCrashReporter) { - gCrashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"] - .getService(Ci.nsICrashReporter); - } - - if (AppConstants.MOZ_CRASHREPORTER && !gCrashReporter) { - throw new Error("The crash reporter is enabled but unavailable"); - } - - return gCrashReporter; -} - -// =================================== -// External API goes here -var CrashReporter = { - addAnnotation(annotation, value) { - getCrashReporter().annotateCrashReport(annotation, value); - }, - - removeAnnotation(annotation) { - getCrashReporter().removeCrashReportAnnotation(annotation); - }, - - get enabled() { - return getCrashReporter().enabled; - }, - - annotations: { -${annotations} - } -};
--- a/toolkit/crashreporter/client/moz.build +++ b/toolkit/crashreporter/client/moz.build @@ -3,17 +3,16 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. if CONFIG['OS_TARGET'] != 'Android': Program('crashreporter') UNIFIED_SOURCES += [ - '../CrashAnnotations.cpp', 'crashreporter.cpp', 'ping.cpp', ] LOCAL_INCLUDES += [ '/toolkit/components/jsoncpp/include', ]
--- a/toolkit/crashreporter/client/ping.cpp +++ b/toolkit/crashreporter/client/ping.cpp @@ -15,18 +15,16 @@ #elif defined(XP_MACOSX) #include <CoreFoundation/CoreFoundation.h> #elif defined(XP_WIN) #include <objbase.h> #endif #include "json/json.h" -#include "CrashAnnotations.h" - using std::string; namespace CrashReporter { struct UUID { uint32_t m0; uint16_t m1; uint16_t m2; @@ -117,25 +115,55 @@ const char kTelemetryUrl[] = "Tele const char kTelemetrySessionId[] = "TelemetrySessionId"; const int kTelemetryVersion = 4; // Create the payload.metadata node of the crash ping using fields extracted // from the .extra file static Json::Value CreateMetadataNode(StringTable& strings) { + // The following list should be kept in sync with the one in CrashManager.jsm + const char *entries[] = { + "AsyncShutdownTimeout", + "AvailablePageFile", + "AvailablePhysicalMemory", + "AvailableVirtualMemory", + "BlockedDllList", + "BlocklistInitFailed", + "BuildID", + "ContainsMemoryReport", + "CrashTime", + "EventLoopNestingLevel", + "ipc_channel_error", + "IsGarbageCollecting", + "LowCommitSpaceEvents", + "MozCrashReason", + "OOMAllocationSize", + "ProductID", + "ProductName", + "ReleaseChannel", + "RemoteType", + "SecondsSinceLastCrash", + "ShutdownProgress", + "StartupCrash", + "SystemMemoryUsePercentage", + "TextureUsage", + "TotalPageFile", + "TotalPhysicalMemory", + "TotalVirtualMemory", + "UptimeTS", + "User32BeforeBlocklist", + "Version", + }; + Json::Value node; - for (auto line : strings) { - Annotation annotation; - - if (AnnotationFromString(annotation, line.first.c_str())) { - if (IsAnnotationWhitelistedForPing(annotation)) { - node[line.first] = line.second; - } + for (auto entry : entries) { + if ((strings.find(entry) != strings.end()) && !strings[entry].empty()) { + node[entry] = strings[entry]; } } return node; } // Create the payload node of the crash ping static Json::Value
deleted file mode 100644 --- a/toolkit/crashreporter/generate_crash_reporter_sources.py +++ /dev/null @@ -1,241 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. - -import string -import sys -import textwrap -import yaml - -############################################################################### -# Language-agnostic functionality # -############################################################################### - -template_header = "/* This file was autogenerated by " \ - "toolkit/crashreporter/generate_crash_reporter_sources.py. DO NOT EDIT */\n\n" - - -def validate_annotations(annotations): - """ Ensure that the annotations have all the required fields """ - - for (name, data) in sorted(annotations.items()): - if "description" not in data: - print("Annotation " + name + " does not have a description\n") - sys.exit(1) - if "type" not in data: - print("Annotation " + name + " does not have a type\n") - sys.exit(1) - else: - annotation_type = data.get("type") - valid_types = ["boolean", "integer", "string"] - if not any(annotation_type == t for t in valid_types): - print("Annotation " + name + " has an unknown type: " + annotation_type + "\n") - sys.exit(1) - - -def read_annotations(annotations_filename): - """Read the annotations from a YAML file. - If an error is encountered quit the program.""" - - try: - with open(annotations_filename, "r") as annotations_file: - annotations = yaml.safe_load(annotations_file) - except (IOError, ValueError) as e: - print("Error parsing " + annotations_filename + ":\n" + str(e) + "\n") - sys.exit(1) - - validate_annotations(annotations) - - return annotations - - -def read_template(template_filename): - """Read the contents of the template. - If an error is encountered quit the program.""" - - try: - with open(template_filename, "r") as template_file: - template = template_file.read() - except IOError as ex: - print("Error when reading " + template_filename + ":\n" + str(ex) + "\n") - sys.exit(1) - - return template - - -def extract_crash_ping_whitelist(annotations): - """Extract an array holding the names of the annotations whitelisted for - inclusion in the crash ping.""" - - return [name - for (name, data) - in sorted(annotations.items()) - if data.get("ping", False)] - - -def extract_content_process_blacklist(annotations): - """Extract an array holding the names of the annotations blacklisted when - read from a content process.""" - - return [name - for (name, data) - in sorted(annotations.items()) - if not data.get("content", True)] - -############################################################################### -# C++ code generation # -############################################################################### - - -def generate_strings(annotations): - """Generate strings corresponding to every annotation.""" - - names = [" \"" + data.get("altname", name) + "\"" - for (name, data) - in sorted(annotations.items())] - - return ",\n".join(names) - - -def generate_enum(annotations): - """Generate the C++ typed enum holding all the annotations and return it - as a string.""" - - enum = "" - - for i, (name, _) in enumerate(sorted(annotations.items())): - enum += " " + name + " = " + str(i) + ",\n" - - enum += " Count = " + str(len(annotations)) - - return enum - - -def generate_array_initializer(contents): - """Generates the initializer for a C++ array of annotations.""" - - initializer = [" Annotation::" + name for name in contents] - - return ",\n".join(initializer) - - -def generate_header(template, annotations): - """Generate a header by filling the template with the the list of - annotations and return it as a string.""" - - whitelist = extract_crash_ping_whitelist(annotations) - blacklist = extract_content_process_blacklist(annotations) - - return template_header + string.Template(template).substitute({ - "enum": generate_enum(annotations), - "strings": generate_strings(annotations), - "whitelist": generate_array_initializer(whitelist), - "blacklist": generate_array_initializer(blacklist), - }) - - -def emit_header(output, template_filename, annotations_filename): - """Generate the C++ header from the template and write it out.""" - - annotations = read_annotations(annotations_filename) - template = read_template(template_filename) - generated_header = generate_header(template, annotations) - - try: - output.write(generated_header) - except IOError as ex: - print("Error while writing out the generated file:\n" + str(ex) + "\n") - sys.exit(1) - -############################################################################### -# JavaScript code generation # -############################################################################### - - -def generate_annotations_fields(annotations): - """Generate the list of JS fields corresponding to the annotations and - return it as a string.""" - - constants = [] - - for i, (name, _) in enumerate(sorted(annotations.items())): - constants.append(" " + name + ": " + str(i + 1) + ",") - - return "\n".join(constants) - - -def generate_jsm(template, annotations): - """Generate the CrashReporter.jsm module by filling the template with the - the list of annotations and return it as a string.""" - - annotations_list = generate_annotations_fields(annotations) - - return template_header + string.Template(template).substitute({ - "annotations": annotations_list, - }) - - -def emit_jsm(output, template_filename, annotations_filename): - """Generate the CrashReporter.jsm module.""" - - annotations = read_annotations(annotations_filename) - template = read_template(template_filename) - generated_jsm = generate_jsm(template, annotations) - - try: - output.write(generated_jsm) - except IOError as ex: - print("Error while writing out the generated file:\n" + str(ex) + "\n") - sys.exit(1) - -############################################################################### -# Java code generation # -############################################################################### - - -def generate_java_array_initializer(contents): - """Generates the initializer for an array of strings. - Effectively turns `["a", "b"]` into ' \"a\",\n \"b\"\n'.""" - - initializer = "" - - for name in contents: - initializer += " \"" + name + "\",\n" - - return initializer.strip(",\n") - - -def generate_class(template, annotations): - """Fill the class template from the list of annotations.""" - - whitelist = extract_crash_ping_whitelist(annotations) - - return template_header + string.Template(template).substitute({ - "whitelist": generate_java_array_initializer(whitelist), - }) - - -def emit_class(output, annotations_filename): - """Generate the CrashReporterConstants.java file.""" - - template = textwrap.dedent("""\ - package org.mozilla.gecko; - - /** - * Constants used by the crash reporter. These are generated so that they - * are kept in sync with the other C++ and JS users. - */ - public class CrashReporterConstants { - public static final String[] ANNOTATION_WHITELIST = { - ${whitelist} - }; - }""") - - annotations = read_annotations(annotations_filename) - generated_class = generate_class(template, annotations) - - try: - output.write(generated_class) - except IOError as ex: - print("Error while writing out the generated file:\n" + str(ex) + "\n") - sys.exit(1)
--- a/toolkit/crashreporter/moz.build +++ b/toolkit/crashreporter/moz.build @@ -4,34 +4,23 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. SPHINX_TREES['crashreporter'] = 'docs' with Files('docs/**'): SCHEDULES.exclusive = ['docs'] -GENERATED_FILES += [ - 'CrashAnnotations.h', - 'CrashReporter.jsm', -] - EXPORTS += [ - '!CrashAnnotations.h', 'nsExceptionHandler.h', ] -EXTRA_JS_MODULES += [ - '!CrashReporter.jsm', -] - JAR_MANIFESTS += ['jar.mn'] UNIFIED_SOURCES = [ - 'CrashAnnotations.cpp', 'nsExceptionHandlerUtils.cpp', ] FINAL_LIBRARY = 'xul' if CONFIG['MOZ_CRASHREPORTER']: if CONFIG['OS_ARCH'] == 'WINNT': DIRS += [ @@ -131,26 +120,11 @@ if CONFIG['MOZ_CRASHREPORTER']: if CONFIG['CC_TYPE'] in ('clang', 'gcc'): CXXFLAGS += ['-Wno-shadow'] else: UNIFIED_SOURCES += [ 'nsDummyExceptionHandler.cpp', ] -# Generate CrashAnnotations.h -crash_annotations = GENERATED_FILES['CrashAnnotations.h'] -crash_annotations.script = 'generate_crash_reporter_sources.py:emit_header' -crash_annotations.inputs = [ - 'CrashAnnotations.h.in', - 'CrashAnnotations.yaml', -] - -# Generate CrashReporter.jsm -crash_reporter_jsm = GENERATED_FILES['CrashReporter.jsm'] -crash_reporter_jsm.script = 'generate_crash_reporter_sources.py:emit_jsm' -crash_reporter_jsm.inputs = [ - 'CrashReporter.jsm.in', - 'CrashAnnotations.yaml', -] with Files('**'): BUG_COMPONENT = ('Toolkit', 'Crash Reporting')
--- a/toolkit/crashreporter/nsDummyExceptionHandler.cpp +++ b/toolkit/crashreporter/nsDummyExceptionHandler.cpp @@ -61,41 +61,24 @@ SetupExtraData(nsIFile* aAppDataDirector nsresult UnsetExceptionHandler() { return NS_ERROR_NOT_IMPLEMENTED; } nsresult -AnnotateCrashReport(Annotation key, bool data) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -AnnotateCrashReport(Annotation key, int data) +AnnotateCrashReport(const nsACString& key, + const nsACString& data) { return NS_ERROR_NOT_IMPLEMENTED; } nsresult -AnnotateCrashReport(Annotation key, unsigned int data) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -AnnotateCrashReport(Annotation key, const nsACString& data) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -RemoveCrashReportAnnotation(Annotation key) +RemoveCrashReportAnnotation(const nsACString& key) { return NS_ERROR_NOT_IMPLEMENTED; } nsresult SetGarbageCollecting(bool collecting) { return NS_ERROR_NOT_IMPLEMENTED;
--- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -7,17 +7,16 @@ #include "nsExceptionHandler.h" #include "nsExceptionHandlerUtils.h" #include "nsAppDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h" #include "nsDirectoryService.h" #include "nsDataHashtable.h" #include "mozilla/ArrayUtils.h" -#include "mozilla/EnumeratedRange.h" #include "mozilla/Services.h" #include "nsIObserverService.h" #include "mozilla/Unused.h" #include "mozilla/Printf.h" #include "mozilla/Sprintf.h" #include "mozilla/SyncRunnable.h" #include "mozilla/TimeStamp.h" #include "mozilla/ipc/CrashReporterClient.h" @@ -229,17 +228,17 @@ static const char* androidStartServiceCo // After targeting API 26 (Oreo) we ned to use a JobIntentService for the background // work regarding crash reporting. That Service needs a unique Job Id. static const char* androidCrashReporterJobId = nullptr; #endif // this holds additional data sent via the API static Mutex* crashReporterAPILock; static Mutex* notesFieldLock; -static AnnotationTable crashReporterAPIData_Table; +static AnnotationTable* crashReporterAPIData_Hash; static nsCString* crashReporterAPIData = nullptr; static nsCString* crashEventAPIData = nullptr; static nsCString* notesField = nullptr; static bool isGarbageCollecting; static uint32_t eventloopNestingLevel = 0; // Avoid a race during application termination. static Mutex* dumpSafetyLock; @@ -320,16 +319,25 @@ public: NS_IMETHOD Run() override; private: uint32_t mPID; }; #endif // MOZ_CRASHREPORTER_INJECTOR +// Crashreporter annotations that we don't send along in subprocess reports. +static const char* kSubprocessBlacklist[] = { + "FramePoisonBase", + "FramePoisonSize", + "StartupCrash", + "StartupTime", + "URL" +}; + // If annotations are attempted before the crash reporter is enabled, // they queue up here. class DelayedNote; nsTArray<nsAutoPtr<DelayedNote> >* gDelayedAnnotations; #if defined(XP_WIN) // the following are used to prevent other DLLs reverting the last chance // exception handler to the windows default. Any attempt to change the @@ -666,26 +674,23 @@ WriteString(PlatformWriter& pw, const ch size_t len = my_strlen(str); #else size_t len = strlen(str); #endif pw.WriteBuffer(str, len); } +template<int N> static void -WriteAnnotation(PlatformWriter& pw, const Annotation name, - const char* value, size_t len = 0) { - WriteString(pw, AnnotationToString(name)); +WriteAnnotation(PlatformWriter& pw, const char (&name)[N], + const char* value) { + WriteLiteral(pw, name); WriteLiteral(pw, "="); - if (len == 0) { - WriteString(pw, value); - } else { - pw.WriteBuffer(value, len); - } + WriteString(pw, value); WriteLiteral(pw, "\n"); }; /** * If minidump_id is null, we assume that dump_path contains the full * dump file path. */ static void @@ -727,28 +732,23 @@ WriteGlobalMemoryStatus(PlatformWriter* conversionFunc(statex.field, buffer, 10); \ if (apiData) { \ WriteAnnotation(*apiData, name, buffer); \ } \ if (eventFile) { \ WriteAnnotation(*eventFile, name, buffer); \ } - WRITE_STATEX_FIELD(dwMemoryLoad, Annotation::SystemMemoryUsePercentage, - ltoa); - WRITE_STATEX_FIELD(ullTotalVirtual, Annotation::TotalVirtualMemory, - _ui64toa); - WRITE_STATEX_FIELD(ullAvailVirtual, Annotation::AvailableVirtualMemory, - _ui64toa); - WRITE_STATEX_FIELD(ullTotalPageFile, Annotation::TotalPageFile, _ui64toa); - WRITE_STATEX_FIELD(ullAvailPageFile, Annotation::AvailablePageFile, - _ui64toa); - WRITE_STATEX_FIELD(ullTotalPhys, Annotation::TotalPhysicalMemory, _ui64toa); - WRITE_STATEX_FIELD(ullAvailPhys, Annotation::AvailablePhysicalMemory, - _ui64toa); + WRITE_STATEX_FIELD(dwMemoryLoad, "SystemMemoryUsePercentage", ltoa); + WRITE_STATEX_FIELD(ullTotalVirtual, "TotalVirtualMemory", _ui64toa); + WRITE_STATEX_FIELD(ullAvailVirtual, "AvailableVirtualMemory", _ui64toa); + WRITE_STATEX_FIELD(ullTotalPageFile, "TotalPageFile", _ui64toa); + WRITE_STATEX_FIELD(ullAvailPageFile, "AvailablePageFile", _ui64toa); + WRITE_STATEX_FIELD(ullTotalPhys, "TotalPhysicalMemory", _ui64toa); + WRITE_STATEX_FIELD(ullAvailPhys, "AvailablePhysicalMemory", _ui64toa); #undef WRITE_STATEX_FIELD } } #endif #if !defined(MOZ_WIDGET_ANDROID) @@ -1030,99 +1030,101 @@ MinidumpCallback( OpenAPIData(apiData, descriptor.path()); #else OpenAPIData(apiData, dump_path, minidump_id); #endif apiData.WriteBuffer(crashReporterAPIData->get(), crashReporterAPIData->Length()); } if (currentSessionId) { - WriteAnnotation(apiData, Annotation::TelemetrySessionId, - currentSessionId); - WriteAnnotation(eventFile, Annotation::TelemetrySessionId, - currentSessionId); + WriteAnnotation(apiData, "TelemetrySessionId", currentSessionId); + WriteAnnotation(eventFile, "TelemetrySessionId", currentSessionId); } - WriteAnnotation(apiData, Annotation::CrashTime, crashTimeString); - WriteAnnotation(eventFile, Annotation::CrashTime, crashTimeString); - - WriteAnnotation(apiData, Annotation::UptimeTS, uptimeTSString); - WriteAnnotation(eventFile, Annotation::UptimeTS, uptimeTSString); + WriteAnnotation(apiData, "CrashTime", crashTimeString); + WriteAnnotation(eventFile, "CrashTime", crashTimeString); + + WriteAnnotation(apiData, "UptimeTS", uptimeTSString); + WriteAnnotation(eventFile, "UptimeTS", uptimeTSString); if (timeSinceLastCrash != 0) { - WriteAnnotation(apiData, Annotation::SecondsSinceLastCrash, + WriteAnnotation(apiData, "SecondsSinceLastCrash", timeSinceLastCrashString); - WriteAnnotation(eventFile, Annotation::SecondsSinceLastCrash, + WriteAnnotation(eventFile, "SecondsSinceLastCrash", timeSinceLastCrashString); } if (isGarbageCollecting) { - WriteAnnotation(apiData, Annotation::IsGarbageCollecting, "1"); - WriteAnnotation(eventFile, Annotation::IsGarbageCollecting, "1"); + WriteAnnotation(apiData, "IsGarbageCollecting", "1"); + WriteAnnotation(eventFile, "IsGarbageCollecting", "1"); } char buffer[128]; if (eventloopNestingLevel > 0) { XP_STOA(eventloopNestingLevel, buffer, 10); - WriteAnnotation(apiData, Annotation::EventLoopNestingLevel, buffer); - WriteAnnotation(eventFile, Annotation::EventLoopNestingLevel, buffer); + WriteAnnotation(apiData, "EventLoopNestingLevel", buffer); + WriteAnnotation(eventFile, "EventLoopNestingLevel", buffer); } #ifdef XP_WIN if (gBreakpadReservedVM) { _ui64toa(uintptr_t(gBreakpadReservedVM), buffer, 10); - WriteAnnotation(apiData, Annotation::BreakpadReserveAddress, buffer); + WriteAnnotation(apiData, "BreakpadReserveAddress", buffer); _ui64toa(kReserveSize, buffer, 10); - WriteAnnotation(apiData, Annotation::BreakpadReserveSize, buffer); + WriteAnnotation(apiData, "BreakpadReserveSize", buffer); } #ifdef HAS_DLL_BLOCKLIST if (apiData.Valid()) { DllBlocklist_WriteNotes(apiData.Handle()); DllBlocklist_WriteNotes(eventFile.Handle()); } #endif WriteGlobalMemoryStatus(&apiData, &eventFile); #endif // XP_WIN char* rust_panic_reason; size_t rust_panic_len; if (get_rust_panic_reason(&rust_panic_reason, &rust_panic_len)) { // rust_panic_reason is not null-terminated. - WriteAnnotation(apiData, Annotation::MozCrashReason, rust_panic_reason, - rust_panic_len); - WriteAnnotation(eventFile, Annotation::MozCrashReason, rust_panic_reason, - rust_panic_len); + WriteLiteral(apiData, "MozCrashReason="); + apiData.WriteBuffer(rust_panic_reason, rust_panic_len); + WriteLiteral(apiData, "\n"); + WriteLiteral(eventFile, "MozCrashReason="); + eventFile.WriteBuffer(rust_panic_reason, rust_panic_len); + WriteLiteral(eventFile, "\n"); } else if (gMozCrashReason) { - WriteAnnotation(apiData, Annotation::MozCrashReason, gMozCrashReason); - WriteAnnotation(eventFile, Annotation::MozCrashReason, gMozCrashReason); + WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason); + WriteAnnotation(eventFile, "MozCrashReason", gMozCrashReason); } if (oomAllocationSizeBuffer[0]) { - WriteAnnotation(apiData, Annotation::OOMAllocationSize, - oomAllocationSizeBuffer); - WriteAnnotation(eventFile, Annotation::OOMAllocationSize, - oomAllocationSizeBuffer); + WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer); + WriteAnnotation(eventFile, "OOMAllocationSize", oomAllocationSizeBuffer); } if (texturesSizeBuffer[0]) { - WriteAnnotation(apiData, Annotation::TextureUsage, texturesSizeBuffer); - WriteAnnotation(eventFile, Annotation::TextureUsage, texturesSizeBuffer); + WriteAnnotation(apiData, "TextureUsage", texturesSizeBuffer); + WriteAnnotation(eventFile, "TextureUsage", texturesSizeBuffer); } if (memoryReportPath) { - WriteAnnotation(apiData, Annotation::ContainsMemoryReport, "1"); - WriteAnnotation(eventFile, Annotation::ContainsMemoryReport, "1"); + WriteLiteral(apiData, "ContainsMemoryReport=1\n"); + WriteLiteral(eventFile, "ContainsMemoryReport=1\n"); } std::function<void(const char*)> getThreadAnnotationCB = - [&] (const char* aValue) -> void { - if (aValue) { - WriteAnnotation(apiData, Annotation::ThreadIdNameMapping, aValue); - WriteAnnotation(eventFile, Annotation::ThreadIdNameMapping, aValue); + [&] (const char * aAnnotation) -> void { + if (aAnnotation) { + WriteLiteral(apiData, "ThreadIdNameMapping="); + WriteLiteral(eventFile, "ThreadIdNameMapping="); + WriteString(apiData, aAnnotation); + WriteString(eventFile, aAnnotation); + WriteLiteral(apiData, "\n"); + WriteLiteral(eventFile, "\n"); } }; GetFlatThreadAnnotation(getThreadAnnotationCB, false); } if (!doReport) { #ifdef XP_WIN TerminateProcess(GetCurrentProcess(), 1); @@ -1279,34 +1281,36 @@ PrepareChildExceptionTimeAnnotations(voi #endif char oomAllocationSizeBuffer[32] = ""; if (gOOMAllocationSize) { XP_STOA(gOOMAllocationSize, oomAllocationSizeBuffer, 10); } if (oomAllocationSizeBuffer[0]) { - WriteAnnotation(apiData, Annotation::OOMAllocationSize, - oomAllocationSizeBuffer); + WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer); } char* rust_panic_reason; size_t rust_panic_len; if (get_rust_panic_reason(&rust_panic_reason, &rust_panic_len)) { // rust_panic_reason is not null-terminated. - WriteAnnotation(apiData, Annotation::MozCrashReason, rust_panic_reason, - rust_panic_len); + WriteLiteral(apiData, "MozCrashReason="); + apiData.WriteBuffer(rust_panic_reason, rust_panic_len); + WriteLiteral(apiData, "\n"); } else if (gMozCrashReason) { - WriteAnnotation(apiData, Annotation::MozCrashReason, gMozCrashReason); + WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason); } std::function<void(const char*)> getThreadAnnotationCB = - [&] (const char * aValue) -> void { - if (aValue) { - WriteAnnotation(apiData, Annotation::ThreadIdNameMapping, aValue); + [&] (const char * aAnnotation) -> void { + if (aAnnotation) { + WriteLiteral(apiData, "ThreadIdNameMapping="); + WriteString(apiData, aAnnotation); + WriteLiteral(apiData, "\n"); } }; GetFlatThreadAnnotation(getThreadAnnotationCB, true); } #ifdef XP_WIN static void ReserveBreakpadVM() @@ -1499,16 +1503,20 @@ nsresult SetExceptionHandler(nsIFile* aX crashReporterAPIData = new nsCString(); crashEventAPIData = new nsCString(); NS_ASSERTION(!crashReporterAPILock, "Shouldn't have a lock yet"); crashReporterAPILock = new Mutex("crashReporterAPILock"); NS_ASSERTION(!notesFieldLock, "Shouldn't have a lock yet"); notesFieldLock = new Mutex("notesFieldLock"); + crashReporterAPIData_Hash = + new nsDataHashtable<nsCStringHashKey,nsCString>(); + NS_ENSURE_TRUE(crashReporterAPIData_Hash, NS_ERROR_OUT_OF_MEMORY); + notesField = new nsCString(); NS_ENSURE_TRUE(notesField, NS_ERROR_OUT_OF_MEMORY); #if !defined(MOZ_WIDGET_ANDROID) // Locate the crash reporter executable nsAutoString crashReporterPath_temp; nsresult rv = LocateExecutable(aXREDirectory, NS_LITERAL_CSTRING(CRASH_REPORTER_FILENAME), @@ -1665,17 +1673,18 @@ nsresult SetExceptionHandler(nsIFile* aX printf_stderr ("SetUnhandledExceptionFilter hook failed; crash reporter is vulnerable.\n"); #endif #endif // store application start time char timeString[32]; time_t startupTime = time(nullptr); XP_TTOA(startupTime, timeString, 10); - AnnotateCrashReport(Annotation::StartupTime, nsDependentCString(timeString)); + AnnotateCrashReport(NS_LITERAL_CSTRING("StartupTime"), + nsDependentCString(timeString)); #if defined(XP_MACOSX) // On OS X, many testers like to see the OS crash reporting dialog // since it offers immediate stack traces. We allow them to set // a default to pass exceptions to the OS handler. Boolean keyExistsAndHasValidFormat = false; Boolean prefValue = ::CFPreferencesGetAppBooleanValue(CFSTR("OSCrashReporter"), kCFPreferencesCurrentApplication, @@ -1919,17 +1928,17 @@ nsresult SetupExtraData(nsIFile* aAppDat if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } nsAutoCString data; if(NS_SUCCEEDED(GetOrInit(dataDirectory, NS_LITERAL_CSTRING("InstallTime") + aBuildID, data, InitInstallTime))) - AnnotateCrashReport(Annotation::InstallTime, data); + AnnotateCrashReport(NS_LITERAL_CSTRING("InstallTime"), data); // this is a little different, since we can't init it with anything, // since it's stored at crash time, and we can't annotate the // crash report with the stored value, since we really want // (now - LastCrash), so we just get a value if it exists, // and store it in a time_t value. if(NS_SUCCEEDED(GetOrInit(dataDirectory, NS_LITERAL_CSTRING("LastCrash"), data, nullptr))) { @@ -1977,19 +1986,18 @@ nsresult UnsetExceptionHandler() // allow SetUnhandledExceptionFilter gBlockUnhandledExceptionFilter = false; #endif delete gExceptionHandler; // do this here in the unlikely case that we succeeded in allocating // our strings but failed to allocate gExceptionHandler. - std::fill(crashReporterAPIData_Table.begin(), - crashReporterAPIData_Table.end(), - EmptyCString()); + delete crashReporterAPIData_Hash; + crashReporterAPIData_Hash = nullptr; delete crashReporterAPILock; crashReporterAPILock = nullptr; delete notesFieldLock; notesFieldLock = nullptr; delete crashReporterAPIData; @@ -2066,18 +2074,22 @@ static void ReplaceChar(nsCString& str, str.BeginReading(iter); iter.advance(pos + replacement.Length() - 1); str.EndReading(end); } } static nsresult -EscapeAnnotation(const nsACString& data, nsCString& escapedData) +EscapeAnnotation(const nsACString& key, const nsACString& data, nsCString& escapedData) { + if (FindInReadable(NS_LITERAL_CSTRING("="), key) || + FindInReadable(NS_LITERAL_CSTRING("\n"), key)) + return NS_ERROR_INVALID_ARG; + if (FindInReadable(NS_LITERAL_CSTRING("\0"), data)) return NS_ERROR_INVALID_ARG; escapedData = data; // escape backslashes ReplaceChar(escapedData, NS_LITERAL_CSTRING("\\"), NS_LITERAL_CSTRING("\\\\")); @@ -2085,35 +2097,35 @@ EscapeAnnotation(const nsACString& data, ReplaceChar(escapedData, NS_LITERAL_CSTRING("\n"), NS_LITERAL_CSTRING("\\n")); return NS_OK; } class DelayedNote { public: - DelayedNote(Annotation aKey, const nsACString& aData) - : mKey(aKey), mData(aData), mType(CrashAnnotation) {} + DelayedNote(const nsACString& aKey, const nsACString& aData) + : mKey(aKey), mData(aData), mType(Annotation) {} explicit DelayedNote(const nsACString& aData) : mData(aData), mType(AppNote) {} void Run() { - if (mType == CrashAnnotation) { + if (mType == Annotation) { AnnotateCrashReport(mKey, mData); } else { AppendAppNotesToCrashReport(mData); } } private: - Annotation mKey; + nsCString mKey; nsCString mData; - enum AnnotationType { CrashAnnotation, AppNote } mType; + enum AnnotationType { Annotation, AppNote } mType; }; static void EnqueueDelayedNote(DelayedNote* aNote) { if (!gDelayedAnnotations) { gDelayedAnnotations = new nsTArray<nsAutoPtr<DelayedNote> >(); } @@ -2127,88 +2139,66 @@ RunAndCleanUpDelayedNotes() for (nsAutoPtr<DelayedNote>& note : *gDelayedAnnotations) { note->Run(); } delete gDelayedAnnotations; gDelayedAnnotations = nullptr; } } -nsresult AnnotateCrashReport(Annotation key, bool data) -{ - return AnnotateCrashReport(key, data ? NS_LITERAL_CSTRING("1") - : NS_LITERAL_CSTRING("0")); -} - -nsresult AnnotateCrashReport(Annotation key, int data) -{ - nsAutoCString dataString; - dataString.AppendInt(data); - - return AnnotateCrashReport(key, dataString); -} - -nsresult AnnotateCrashReport(Annotation key, unsigned int data) -{ - nsAutoCString dataString; - dataString.AppendInt(data); - - return AnnotateCrashReport(key, dataString); -} - -nsresult AnnotateCrashReport(Annotation key, const nsACString& data) +nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data) { if (!GetEnabled()) return NS_ERROR_NOT_INITIALIZED; nsCString escapedData; - nsresult rv = EscapeAnnotation(data, escapedData); + nsresult rv = EscapeAnnotation(key, data, escapedData); if (NS_FAILED(rv)) return rv; if (!XRE_IsParentProcess()) { // The newer CrashReporterClient can be used from any thread. if (RefPtr<CrashReporterClient> client = CrashReporterClient::GetSingleton()) { - client->AnnotateCrashReport(key, escapedData); + client->AnnotateCrashReport(nsCString(key), escapedData); return NS_OK; } // EnqueueDelayedNote() can only be called on the main thread. MOZ_RELEASE_ASSERT(NS_IsMainThread()); EnqueueDelayedNote(new DelayedNote(key, data)); return NS_OK; } MutexAutoLock lock(*crashReporterAPILock); - crashReporterAPIData_Table[key] = escapedData; + crashReporterAPIData_Hash->Put(key, escapedData); // now rebuild the file contents crashReporterAPIData->Truncate(0); crashEventAPIData->Truncate(0); - for (auto key : MakeEnumeratedRange(Annotation::Count)) { - nsDependentCString str(AnnotationToString(key)); - nsCString entry = crashReporterAPIData_Table[key]; + for (auto it = crashReporterAPIData_Hash->Iter(); !it.Done(); it.Next()) { + const nsACString& key = it.Key(); + nsCString entry = it.Data(); if (!entry.IsEmpty()) { NS_NAMED_LITERAL_CSTRING(kEquals, "="); NS_NAMED_LITERAL_CSTRING(kNewline, "\n"); - nsAutoCString line = str + kEquals + entry + kNewline; + nsAutoCString line = key + kEquals + entry + kNewline; crashReporterAPIData->Append(line); crashEventAPIData->Append(line); } } return NS_OK; } -nsresult RemoveCrashReportAnnotation(Annotation key) +nsresult RemoveCrashReportAnnotation(const nsACString& key) { - return AnnotateCrashReport(key, EmptyCString()); + return AnnotateCrashReport(key, NS_LITERAL_CSTRING("")); } nsresult SetGarbageCollecting(bool collecting) { if (!GetEnabled()) return NS_ERROR_NOT_INITIALIZED; isGarbageCollecting = collecting; @@ -2235,17 +2225,17 @@ nsresult AppendAppNotesToCrashReport(con if (FindInReadable(NS_LITERAL_CSTRING("\0"), data)) return NS_ERROR_INVALID_ARG; if (!XRE_IsParentProcess()) { // Since we don't go through AnnotateCrashReport in the parent process, // we must ensure that the data is escaped and valid before the parent // sees it. nsCString escapedData; - nsresult rv = EscapeAnnotation(data, escapedData); + nsresult rv = EscapeAnnotation(NS_LITERAL_CSTRING("Notes"), data, escapedData); if (NS_FAILED(rv)) return rv; if (RefPtr<CrashReporterClient> client = CrashReporterClient::GetSingleton()) { client->AppendAppNotes(escapedData); return NS_OK; } @@ -2254,31 +2244,30 @@ nsresult AppendAppNotesToCrashReport(con EnqueueDelayedNote(new DelayedNote(data)); return NS_OK; } MutexAutoLock lock(*notesFieldLock); notesField->Append(data); - return AnnotateCrashReport(Annotation::Notes, *notesField); + return AnnotateCrashReport(NS_LITERAL_CSTRING("Notes"), *notesField); } // Returns true if found, false if not found. static bool -GetAnnotation(CrashReporter::Annotation key, nsACString& data) +GetAnnotation(const nsACString& key, nsACString& data) { if (!gExceptionHandler) return false; MutexAutoLock lock(*crashReporterAPILock); - nsCString entry = crashReporterAPIData_Table[key]; - if (entry.IsEmpty()) { + nsAutoCString entry; + if (!crashReporterAPIData_Hash->Get(key, &entry)) return false; - } data = entry; return true; } nsresult RegisterAppMemory(void* ptr, size_t length) { if (!GetEnabled()) @@ -2316,24 +2305,25 @@ void SetIncludeContextHeap(bool aValue) #endif } bool GetServerURL(nsACString& aServerURL) { if (!gExceptionHandler) return false; - return GetAnnotation(CrashReporter::Annotation::ServerURL, aServerURL); + return GetAnnotation(NS_LITERAL_CSTRING("ServerURL"), aServerURL); } nsresult SetServerURL(const nsACString& aServerURL) { // store server URL with the API data // the client knows to handle this specially - return AnnotateCrashReport(Annotation::ServerURL, aServerURL); + return AnnotateCrashReport(NS_LITERAL_CSTRING("ServerURL"), + aServerURL); } nsresult SetRestartArgs(int argc, char** argv) { if (!gExceptionHandler) return NS_OK; @@ -2946,21 +2936,35 @@ AppendExtraData(const nsAString& id, con if (!GetExtraFileForID(id, getter_AddRefs(extraFile))) return false; return AppendExtraData(extraFile, data); } //----------------------------------------------------------------------------- // Helpers for AppendExtraData() // +struct Blacklist { + Blacklist() : mItems(nullptr), mLen(0) { } + Blacklist(const char** items, int len) : mItems(items), mLen(len) { } + + bool Contains(const nsACString& key) const { + for (int i = 0; i < mLen; ++i) + if (key.EqualsASCII(mItems[i])) + return true; + return false; + } + + const char** mItems; + const int mLen; +}; + static void -WriteAnnotation(PRFileDesc* fd, const Annotation key, const nsACString& value) +WriteAnnotation(PRFileDesc* fd, const nsACString& key, const nsACString& value) { - const char* annotation = AnnotationToString(key); - PR_Write(fd, annotation, strlen(annotation)); + PR_Write(fd, key.BeginReading(), key.Length()); PR_Write(fd, "=", 1); PR_Write(fd, value.BeginReading(), value.Length()); PR_Write(fd, "\n", 1); } template<int N> static void WriteLiteral(PRFileDesc* fd, const char (&str)[N]) @@ -2970,70 +2974,68 @@ WriteLiteral(PRFileDesc* fd, const char /* * If accessing the AnnotationTable |data| argument requires locks, the * caller should ensure the required locks are already held. */ static bool WriteExtraData(nsIFile* extraFile, const AnnotationTable& data, + const Blacklist& blacklist, bool writeCrashTime=false, - bool truncate=false, - bool content=false) + bool truncate=false) { PRFileDesc* fd; int truncOrAppend = truncate ? PR_TRUNCATE : PR_APPEND; nsresult rv = extraFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | truncOrAppend, 0600, &fd); if (NS_FAILED(rv)) return false; - for (auto key : MakeEnumeratedRange(Annotation::Count)) { - nsCString value = data[key]; - // Skip entries in the blacklist and empty entries. - if ((content && IsAnnotationBlacklistedForContent(key)) || - value.IsEmpty()) { - continue; + for (auto iter = data.ConstIter(); !iter.Done(); iter.Next()) { + // Skip entries in the blacklist. + const nsACString& key = iter.Key(); + if (blacklist.Contains(key)) { + continue; } - WriteAnnotation(fd, key, value); + WriteAnnotation(fd, key, iter.Data()); } if (writeCrashTime) { time_t crashTime = time(nullptr); char crashTimeString[32]; XP_TTOA(crashTime, crashTimeString, 10); WriteAnnotation(fd, - Annotation::CrashTime, + nsDependentCString("CrashTime"), nsDependentCString(crashTimeString)); double uptimeTS = (TimeStamp::NowLoRes() - TimeStamp::ProcessCreation()).ToSecondsSigDigits(); char uptimeTSString[64]; SimpleNoCLibDtoA(uptimeTS, uptimeTSString, sizeof(uptimeTSString)); WriteAnnotation(fd, - Annotation::UptimeTS, + nsDependentCString("UptimeTS"), nsDependentCString(uptimeTSString)); } if (memoryReportPath) { - WriteAnnotation(fd, Annotation::ContainsMemoryReport, - NS_LITERAL_CSTRING("1")); + WriteLiteral(fd, "ContainsMemoryReport=1\n"); } PR_Close(fd); return true; } bool AppendExtraData(nsIFile* extraFile, const AnnotationTable& data) { - return WriteExtraData(extraFile, data); + return WriteExtraData(extraFile, data, Blacklist()); } static bool IsDataEscaped(char* aData) { if (strchr(aData, '\n')) { // There should not be any newlines return false; @@ -3068,55 +3070,47 @@ ReadAndValidateExceptionTimeAnnotations( if (dataLen > 0 && data[dataLen - 1] == '\n') { data[dataLen - 1] = 0; --dataLen; } // There should not be any newlines in the key if (strchr(line, '\n')) { break; } - // The annotation sould be known - Annotation annotation; - if (!AnnotationFromString(annotation, line)) { - break; - } // Data should have been escaped by the child if (!IsDataEscaped(data)) { break; } // Looks good, save the (line,data) pair - aAnnotations[annotation] = nsDependentCString(data, dataLen); + aAnnotations.Put(nsDependentCString(line), + nsDependentCString(data, dataLen)); } } /** - * Writes extra data in the .extra file corresponding to the specified - * minidump. If `content` is set to true then this assumes that of a child - * process. - * * NOTE: One side effect of this function is that it deletes the * GeckoChildCrash<pid>.extra file if it exists, once processed. */ static bool WriteExtraForMinidump(nsIFile* minidump, uint32_t pid, - bool content, + const Blacklist& blacklist, nsIFile** extraFile) { nsCOMPtr<nsIFile> extra; if (!GetExtraFileForMinidump(minidump, getter_AddRefs(extra))) { return false; } { MutexAutoLock lock(*crashReporterAPILock); - if (!WriteExtraData(extra, crashReporterAPIData_Table, + if (!WriteExtraData(extra, *crashReporterAPIData_Hash, + blacklist, true /*write crash time*/, - true /*truncate*/, - content)) { + true /*truncate*/)) { return false; } } if (pid && processToCrashFd.count(pid)) { PRFileDesc* prFd = processToCrashFd[pid]; processToCrashFd.erase(pid); FILE* fd; @@ -3211,20 +3205,21 @@ OnChildProcessDumpRequested(void* aConte uint32_t pid = #ifdef XP_MACOSX aClientInfo.pid(); #else aClientInfo->pid(); #endif - if (!WriteExtraForMinidump(minidump, pid, /* content */ true, - getter_AddRefs(extraFile))) { + if (!WriteExtraForMinidump(minidump, pid, + Blacklist(kSubprocessBlacklist, + ArrayLength(kSubprocessBlacklist)), + getter_AddRefs(extraFile))) return; - } if (ShouldReport()) { nsCOMPtr<nsIFile> memoryReport; if (memoryReportPath) { CreateFileFromPath(memoryReportPath, getter_AddRefs(memoryReport)); MOZ_ASSERT(memoryReport); } MoveToPending(minidump, extraFile, memoryReport); @@ -3737,18 +3732,17 @@ PairedDumpCallbackExtra( #ifdef XP_WIN32 nullptr, nullptr, #endif succeeded); nsCOMPtr<nsIFile>& minidump = *static_cast< nsCOMPtr<nsIFile>* >(context); nsCOMPtr<nsIFile> extra; - return WriteExtraForMinidump(minidump, 0, /* content */ false, - getter_AddRefs(extra)); + return WriteExtraForMinidump(minidump, 0, Blacklist(), getter_AddRefs(extra)); } ThreadId CurrentThreadId() { #if defined(XP_WIN) return ::GetCurrentThreadId(); #elif defined(XP_LINUX)
--- a/toolkit/crashreporter/nsExceptionHandler.h +++ b/toolkit/crashreporter/nsExceptionHandler.h @@ -8,19 +8,16 @@ // configured with --disable-crashreporter. If you add or remove a function // from this header you must update both implementations otherwise you'll break // builds that disable the crash reporter. #ifndef nsExceptionHandler_h__ #define nsExceptionHandler_h__ #include "mozilla/Assertions.h" -#include "mozilla/EnumeratedArray.h" - -#include "CrashAnnotations.h" #include <functional> #include <stddef.h> #include <stdint.h> #include "nsError.h" #include "nsString.h" #include "prio.h" @@ -35,16 +32,18 @@ #include <mach/mach.h> #endif #if defined(XP_LINUX) #include <signal.h> #endif class nsIFile; +template<class KeyClass, class DataType> class nsDataHashtable; +class nsCStringHashKey; namespace CrashReporter { /** * Returns true if the crash reporter is using the dummy implementation. */ static inline bool IsDummy() { @@ -88,21 +87,18 @@ bool GetServerURL(nsACString& aServe nsresult SetServerURL(const nsACString& aServerURL); bool GetMinidumpPath(nsAString& aPath); nsresult SetMinidumpPath(const nsAString& aPath); // AnnotateCrashReport, RemoveCrashReportAnnotation and // AppendAppNotesToCrashReport may be called from any thread in a chrome // process, but may only be called from the main thread in a content process. -nsresult AnnotateCrashReport(Annotation key, bool data); -nsresult AnnotateCrashReport(Annotation key, int data); -nsresult AnnotateCrashReport(Annotation key, unsigned int data); -nsresult AnnotateCrashReport(Annotation key, const nsACString& data); -nsresult RemoveCrashReportAnnotation(Annotation key); +nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data); +nsresult RemoveCrashReportAnnotation(const nsACString& key); nsresult AppendAppNotesToCrashReport(const nsACString& data); void AnnotateOOMAllocationSize(size_t size); void AnnotateTexturesSize(size_t size); nsresult SetGarbageCollecting(bool collecting); void SetEventloopNestingLevel(uint32_t level); void SetMinidumpAnalysisAllThreads(); @@ -112,18 +108,17 @@ nsresult SetupExtraData(nsIFile* aAppDat // Registers an additional memory region to be included in the minidump nsresult RegisterAppMemory(void* ptr, size_t length); nsresult UnregisterAppMemory(void* ptr); // Include heap regions of the crash context. void SetIncludeContextHeap(bool aValue); // Functions for working with minidumps and .extras -typedef mozilla::EnumeratedArray<Annotation, Annotation::Count, nsCString> - AnnotationTable; +typedef nsDataHashtable<nsCStringHashKey, nsCString> AnnotationTable; void DeleteMinidumpFilesForID(const nsAString& id); bool GetMinidumpForID(const nsAString& id, nsIFile** minidump); bool GetIDFromMinidump(nsIFile* minidump, nsAString& id); bool GetExtraFileForID(const nsAString& id, nsIFile** extraFile); bool GetExtraFileForMinidump(nsIFile* minidump, nsIFile** extraFile); bool AppendExtraData(const nsAString& id, const AnnotationTable& data); bool AppendExtraData(nsIFile* extraFile, const AnnotationTable& data);
--- a/toolkit/crashreporter/test/unit/crasher_subprocess_head.js +++ b/toolkit/crashreporter/test/unit/crasher_subprocess_head.js @@ -1,9 +1,8 @@ -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); // enable crash reporting first var cwd = Services.dirsvc.get("CurWorkD", Ci.nsIFile); // get the temp dir var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); var _tmpd = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
--- a/toolkit/crashreporter/test/unit/head_crashreporter.js +++ b/toolkit/crashreporter/test/unit/head_crashreporter.js @@ -1,9 +1,8 @@ -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm"); ChromeUtils.import("resource://gre/modules/osfile.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm", this); ChromeUtils.import("resource://testing-common/AppData.jsm", this); ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); function getEventDir() { return OS.Path.join(do_get_tempdir().path, "crash-events"); }
--- a/toolkit/crashreporter/test/unit/test_crash_abort.js +++ b/toolkit/crashreporter/test/unit/test_crash_abort.js @@ -1,16 +1,15 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ function run_test() { // Try crashing with an abort(). do_crash(function() { crashType = CrashTestUtils.CRASH_ABORT; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "TestValue"); + crashReporter.annotateCrashReport("TestKey", "TestValue"); }, function(mdump, extra) { Assert.equal(extra.TestKey, "TestValue"); }, // process will exit with a zero exit status true); }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure.js +++ b/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure.js @@ -2,20 +2,19 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_crash_after_js_large_allocation_failure.js | Can't test crashreporter in a non-libxul build.\n"); return; } do_crash( function() { crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "Yes"); + crashReporter.annotateCrashReport("TestingOOMCrash", "Yes"); Cu.getJSTestingFunctions().reportLargeAllocationFailure(); Cu.forceGC(); }, function(mdump, extra) { - Assert.equal(extra.TestKey, "Yes"); + Assert.equal(extra.TestingOOMCrash, "Yes"); Assert.equal(false, "JSOutOfMemory" in extra); Assert.equal(extra.JSLargeAllocationFailure, "Recovered"); }, true); }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure_reporting.js +++ b/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure_reporting.js @@ -2,24 +2,23 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_crash_after_js_oom_reporting.js | Can't test crashreporter in a non-libxul build.\n"); return; } do_crash( function() { crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "Yes"); + crashReporter.annotateCrashReport("TestingOOMCrash", "Yes"); function crashWhileReporting() { CrashTestUtils.crash(crashType); } Services.obs.addObserver(crashWhileReporting, "memory-pressure"); Cu.getJSTestingFunctions().reportLargeAllocationFailure(); }, function(mdump, extra) { - Assert.equal(extra.TestKey, "Yes"); + Assert.equal(extra.TestingOOMCrash, "Yes"); Assert.equal(extra.JSLargeAllocationFailure, "Reporting"); }, true); }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_oom_recovered.js +++ b/toolkit/crashreporter/test/unit/test_crash_after_js_oom_recovered.js @@ -2,19 +2,18 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_crash_after_js_oom_recovered.js | Can't test crashreporter in a non-libxul build.\n"); return; } do_crash( function() { crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "Yes"); + crashReporter.annotateCrashReport("TestingOOMCrash", "Yes"); Cu.getJSTestingFunctions().reportOutOfMemory(); Cu.forceGC(); }, function(mdump, extra) { - Assert.equal(extra.TestKey, "Yes"); + Assert.equal(extra.TestingOOMCrash, "Yes"); Assert.equal(extra.JSOutOfMemory, "Recovered"); }, true); }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported.js +++ b/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported.js @@ -2,27 +2,26 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_crash_after_js_oom_reported.js | Can't test crashreporter in a non-libxul build.\n"); return; } do_crash( function() { crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "Yes"); + crashReporter.annotateCrashReport("TestingOOMCrash", "Yes"); // GC now to avoid having it happen randomly later, which would make the // test bogusly fail. See comment below. Cu.forceGC(); Cu.getJSTestingFunctions().reportOutOfMemory(); }, function(mdump, extra) { - Assert.equal(extra.TestKey, "Yes"); + Assert.equal(extra.TestingOOMCrash, "Yes"); // The JSOutOfMemory field is absent if the JS engine never reported OOM, // "Reported" if it did, and "Recovered" if it reported OOM but // subsequently completed a full GC cycle. Since this test calls // reportOutOfMemory() and then crashes, we expect "Reported". // // Theoretically, GC can happen any time, so it is just possible that // this property could be "Recovered" even if the implementation is
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported_2.js +++ b/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported_2.js @@ -2,24 +2,23 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_crash_after_js_oom_reported_2.js | Can't test crashreporter in a non-libxul build.\n"); return; } do_crash( function() { crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "Yes"); + crashReporter.annotateCrashReport("TestingOOMCrash", "Yes"); Cu.getJSTestingFunctions().reportOutOfMemory(); Cu.forceGC(); // recover from first OOM Cu.getJSTestingFunctions().reportOutOfMemory(); }, function(mdump, extra) { - Assert.equal(extra.TestKey, "Yes"); + Assert.equal(extra.TestingOOMCrash, "Yes"); // Technically, GC can happen at any time, but it would be really // peculiar for it to happen again heuristically right after a GC was // forced. If extra.JSOutOfMemory is "Recovered" here, that's most // likely a bug in the error reporting machinery. Assert.equal(extra.JSOutOfMemory, "Reported"); }, true);
--- a/toolkit/crashreporter/test/unit/test_crash_moz_crash.js +++ b/toolkit/crashreporter/test/unit/test_crash_moz_crash.js @@ -1,14 +1,13 @@ function run_test() { // Try crashing with a runtime abort do_crash(function() { crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "TestValue"); + crashReporter.annotateCrashReport("TestKey", "TestValue"); }, function(mdump, extra) { Assert.equal(extra.TestKey, "TestValue"); Assert.equal(false, "OOMAllocationSize" in extra); Assert.equal(false, "JSOutOfMemory" in extra); Assert.equal(false, "JSLargeAllocationFailure" in extra); }, // process will exit with a zero exit status
--- a/toolkit/crashreporter/test/unit/test_crash_oom.js +++ b/toolkit/crashreporter/test/unit/test_crash_oom.js @@ -2,18 +2,17 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_crash_oom.js | Can't test crashreporter in a non-libxul build.\n"); return; } do_crash( function() { crashType = CrashTestUtils.CRASH_OOM; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "Yes"); + crashReporter.annotateCrashReport("TestingOOMCrash", "Yes"); }, function(mdump, extra) { - Assert.equal(extra.TestKey, "Yes"); + Assert.equal(extra.TestingOOMCrash, "Yes"); Assert.ok("OOMAllocationSize" in extra); Assert.ok(Number(extra.OOMAllocationSize) > 0); }, true); }
--- a/toolkit/crashreporter/test/unit/test_crash_purevirtual.js +++ b/toolkit/crashreporter/test/unit/test_crash_purevirtual.js @@ -8,17 +8,16 @@ function run_test() { if (isOSX) { dump("INFO | test_crash_purevirtual.js | TODO: purecalls not caught on OS X\n"); return; } // Try crashing with a pure virtual call do_crash(function() { crashType = CrashTestUtils.CRASH_PURE_VIRTUAL_CALL; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "TestValue"); + crashReporter.annotateCrashReport("TestKey", "TestValue"); }, function(mdump, extra) { Assert.equal(extra.TestKey, "TestValue"); }, // process will exit with a zero exit status true); }
--- a/toolkit/crashreporter/test/unit/test_crash_uncaught_exception.js +++ b/toolkit/crashreporter/test/unit/test_crash_uncaught_exception.js @@ -1,17 +1,16 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ function run_test() { // Try crashing with an uncaught exception. do_crash(function() { crashType = CrashTestUtils.CRASH_UNCAUGHT_EXCEPTION; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "TestValue"); + crashReporter.annotateCrashReport("TestKey", "TestValue"); }, function(mdump, extra) { Assert.equal(extra.TestKey, "TestValue"); }, // process will exit with a zero exit status true); }
--- a/toolkit/crashreporter/test/unit/test_crashreporter.js +++ b/toolkit/crashreporter/test/unit/test_crashreporter.js @@ -34,60 +34,43 @@ function run_test() { // check getting/setting minidumpPath // it should be $TEMP by default, but I'm not sure if we can exactly test that // this will at least test that it doesn't throw Assert.notEqual(cr.minidumpPath.path, ""); var cwd = do_get_cwd(); cr.minidumpPath = cwd; Assert.equal(cr.minidumpPath.path, cwd.path); - // Test annotateCrashReport() try { - cr.annotateCrashReport(undefined, ""); - do_throw("Calling annotateCrashReport() with an undefined key should have thrown!"); + cr.annotateCrashReport("equal=equal", ""); + do_throw("Calling annotateCrashReport() with an '=' in key should have thrown!"); } catch (ex) { Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG); } try { - cr.annotateCrashReport(1000000, ""); - do_throw("Calling annotateCrashReport() with a bogus key should have thrown!"); + cr.annotateCrashReport("new\nline", ""); + do_throw("Calling annotateCrashReport() with a '\\n' in key should have thrown!"); } catch (ex) { Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG); } try { - cr.annotateCrashReport(CrashReporter.annotations.TestKey, "da\0ta"); + cr.annotateCrashReport("", "da\0ta"); do_throw("Calling annotateCrashReport() with a '\\0' in data should have thrown!"); } catch (ex) { Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG); } - cr.annotateCrashReport(CrashReporter.annotations.TestKey, "testData1"); + cr.annotateCrashReport("testKey", "testData1"); // Replace previous data. - cr.annotateCrashReport(CrashReporter.annotations.TestKey, "testData2"); + cr.annotateCrashReport("testKey", "testData2"); try { cr.appendAppNotesToCrashReport("da\0ta"); do_throw("Calling appendAppNotesToCrashReport() with a '\\0' in data should have thrown!"); } catch (ex) { Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG); } cr.appendAppNotesToCrashReport("additional testData3"); // Add more data. cr.appendAppNotesToCrashReport("additional testData4"); - // Test removeCrashReportAnnotation() - try { - cr.removeCrashReportAnnotation(undefined); - do_throw("Calling removeCrashReportAnnotation() with an undefined key should have thrown!"); - } catch (ex) { - Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG); - } - try { - cr.removeCrashReportAnnotation(1000000); - do_throw("Calling removeCrashReportAnnotation() with a bogus key should have thrown!"); - } catch (ex) { - Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG); - } - cr.removeCrashReportAnnotation(CrashReporter.annotations.TestKey); - - // Testing setting the minidumpPath field cr.minidumpPath = cwd; Assert.equal(cr.minidumpPath.path, cwd.path); }
--- a/toolkit/crashreporter/test/unit/test_crashreporter_crash.js +++ b/toolkit/crashreporter/test/unit/test_crashreporter_crash.js @@ -28,37 +28,30 @@ function run_test() { } if (is_win7_or_newer) Assert.ok(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_MEMORY_INFO_LIST_STREAM)); }); // check setting some basic data do_crash(function() { // Add various annotations - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "TestValue"); - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestUnicode, "\u{1F4A9}"); - // Some annotations have an alternate form when written out, Addons - // for example will be written out as Add-ons - crashReporter.annotateCrashReport(CrashReporter.annotations.Addons, - "test%40mozilla.org:0.1"); + crashReporter.annotateCrashReport("TestKey", "TestValue"); + crashReporter.annotateCrashReport("\u2665", "\u{1F4A9}"); crashReporter.appendAppNotesToCrashReport("Junk"); crashReporter.appendAppNotesToCrashReport("MoreJunk"); // TelemetrySession setup will trigger the session annotation let scope = {}; ChromeUtils.import("resource://gre/modules/TelemetryController.jsm", scope); scope.TelemetryController.testSetup(); }, function(mdump, extra) { Assert.equal(extra.TestKey, "TestValue"); - Assert.equal(extra.TestUnicode, "\u{1F4A9}"); + Assert.equal(extra["\u2665"], "\u{1F4A9}"); Assert.equal(extra.Notes, "JunkMoreJunk"); - Assert.equal(extra["Add-ons"], "test%40mozilla.org:0.1"); const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; Assert.ok("TelemetrySessionId" in extra, "The TelemetrySessionId field is present in the extra file"); Assert.ok(UUID_REGEX.test(extra.TelemetrySessionId), "The TelemetrySessionId is a UUID"); Assert.ok(!("TelemetryClientId" in extra), "The TelemetryClientId field is omitted by default"); Assert.ok(!("TelemetryServerURL" in extra),
--- a/toolkit/crashreporter/test/unit/test_event_files.js +++ b/toolkit/crashreporter/test/unit/test_event_files.js @@ -19,18 +19,17 @@ add_task(async function test_main_proces let count = await new Promise((resolve, reject) => { do_crash( function() { // TelemetrySession setup will trigger the session annotation let scope = {}; ChromeUtils.import("resource://gre/modules/TelemetryController.jsm", scope); scope.TelemetryController.testSetup(); crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.ShutdownProgress, "event-test"); + crashReporter.annotateCrashReport("ShutdownProgress", "event-test"); }, (minidump, extra) => { basename = minidump.leafName; cm._eventsDirs = [getEventDir()]; cm.aggregateEventsFiles().then(resolve, reject); }, true);
--- a/toolkit/crashreporter/test/unit/test_oom_annotation_windows.js +++ b/toolkit/crashreporter/test/unit/test_oom_annotation_windows.js @@ -2,21 +2,20 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_crash_oom.js | Can't test crashreporter in a non-libxul build.\n"); return; } do_crash( function() { crashType = CrashTestUtils.CRASH_OOM; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "Yes"); + crashReporter.annotateCrashReport("TestingOOMCrash", "Yes"); }, function(mdump, extra) { - Assert.equal(extra.TestKey, "Yes"); + Assert.equal(extra.TestingOOMCrash, "Yes"); Assert.ok("OOMAllocationSize" in extra); Assert.ok(Number(extra.OOMAllocationSize) > 0); Assert.ok("SystemMemoryUsePercentage" in extra); Assert.ok("TotalVirtualMemory" in extra); Assert.ok("AvailableVirtualMemory" in extra); Assert.ok("TotalPageFile" in extra); Assert.ok("AvailablePageFile" in extra); Assert.ok("TotalPhysicalMemory" in extra);
--- a/toolkit/crashreporter/test/unit_ipc/test_content_annotation.js +++ b/toolkit/crashreporter/test/unit_ipc/test_content_annotation.js @@ -5,18 +5,17 @@ function run_test() { if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { dump("INFO | test_content_annotation.js | Can't test crashreporter in a non-libxul build.\n"); return; } // Try crashing with a runtime abort do_content_crash(function() { crashType = CrashTestUtils.CRASH_MOZ_CRASH; - crashReporter.annotateCrashReport( - CrashReporter.annotations.TestKey, "TestValue"); + crashReporter.annotateCrashReport("TestKey", "TestValue"); crashReporter.appendAppNotesToCrashReport("!!!foo!!!"); }, function(mdump, extra) { Assert.equal(extra.TestKey, "TestValue"); Assert.ok("StartupTime" in extra); Assert.ok("ProcessType" in extra); Assert.notEqual(extra.Notes.indexOf("!!!foo!!!"), -1); });
--- a/toolkit/modules/WebNavigationChild.jsm +++ b/toolkit/modules/WebNavigationChild.jsm @@ -1,24 +1,28 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["WebNavigationChild"]; -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); +ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.defineModuleGetter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm"); ChromeUtils.defineModuleGetter(this, "Utils", "resource://gre/modules/sessionstore/Utils.jsm"); +XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter", + "@mozilla.org/xre/app-info;1", + "nsICrashReporter"); + class WebNavigationChild { constructor(mm) { this.mm = mm; this.mm.addMessageListener("WebNavigation:GoBack", this); this.mm.addMessageListener("WebNavigation:GoForward", this); this.mm.addMessageListener("WebNavigation:GotoIndex", this); this.mm.addMessageListener("WebNavigation:LoadURI", this); @@ -101,17 +105,17 @@ class WebNavigationChild { let url = Services.io.newURI(uri); // If the current URI contains a username/password, remove it. url = url.mutate() .setUserPass("") .finalize(); annotation = url.spec; } catch (ex) { /* Ignore failures to parse and failures on about: URIs. */ } - CrashReporter.addAnnotation(CrashReporter.annotations.URL, annotation); + CrashReporter.annotateCrashReport("URL", annotation); } if (referrer) referrer = Services.io.newURI(referrer); if (postData) postData = Utils.makeInputStream(postData); if (headers) headers = Utils.makeInputStream(headers); if (baseURI)
--- a/toolkit/modules/WebProgressChild.jsm +++ b/toolkit/modules/WebProgressChild.jsm @@ -1,22 +1,24 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["WebProgressChild"]; -ChromeUtils.import("resource://gre/modules/CrashReporter.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.defineModuleGetter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm"); +XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter", + "@mozilla.org/xre/app-info;1", + "nsICrashReporter"); XPCOMUtils.defineLazyServiceGetter(this, "serializationHelper", "@mozilla.org/network/serialization-helper;1", "nsISerializationHelper"); class WebProgressChild { constructor(mm) { this.mm = mm; @@ -171,17 +173,17 @@ class WebProgressChild { if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) { let uri = aLocationURI; try { // If the current URI contains a username/password, remove it. uri = uri.mutate() .setUserPass("") .finalize(); } catch (ex) { /* Ignore failures on about: URIs. */ } - CrashReporter.addAnnotation(CrashReporter.annotations.URL, uri.spec); + CrashReporter.annotateCrashReport("URL", uri.spec); } } this._send("Content:LocationChange", json, objects); } // Note: Because the nsBrowserStatusFilter timeout runnable is // SystemGroup-labeled, this method should not modify this.mm.content DOM or
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm +++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm @@ -2,21 +2,17 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ /* eslint "mozilla/no-aArgs": 1 */ /* eslint "no-unused-vars": [2, {"args": "none", "varsIgnorePattern": "^(Cc|Ci|Cr|Cu|EXPORTED_SYMBOLS)$"}] */ /* eslint "semi": [2, "always"] */ /* eslint "valid-jsdoc": [2, {requireReturn: false}] */ -var EXPORTED_SYMBOLS = [ - "AddonTestUtils", - "MockAsyncShutdown", - "MockCrashReporter", -]; +var EXPORTED_SYMBOLS = ["AddonTestUtils", "MockAsyncShutdown"]; const CERTDB_CONTRACTID = "@mozilla.org/security/x509certdb;1"; Cu.importGlobalProperties(["fetch", "TextEncoder"]); ChromeUtils.import("resource://gre/modules/AsyncShutdown.jsm"); ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); @@ -24,19 +20,16 @@ ChromeUtils.import("resource://gre/modul ChromeUtils.import("resource://gre/modules/Timer.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {}); const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm", {}); ChromeUtils.defineModuleGetter(this, "Extension", "resource://gre/modules/Extension.jsm"); -ChromeUtils.defineModuleGetter(this, "CrashReporter", - "resource://gre/modules/CrashReporter.jsm"); - XPCOMUtils.defineLazyGetter(this, "Management", () => { let {Management} = ChromeUtils.import("resource://gre/modules/Extension.jsm", {}); return Management; }); ChromeUtils.defineModuleGetter(this, "FileTestUtils", "resource://testing-common/FileTestUtils.jsm"); ChromeUtils.defineModuleGetter(this, "HttpServer", @@ -183,38 +176,16 @@ class MockBlocklist { async getPluginBlocklistState(plugin, version, appVersion, toolkitVersion) { await new Promise(r => setTimeout(r, 150)); return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; } } MockBlocklist.prototype.QueryInterface = ChromeUtils.generateQI(["nsIBlocklistService"]); -// Mock the crash reporter wrapper so that we can inspect the annotations -var MockCrashReporter = { - addAnnotation(annotation, value) { - this.checkAnnotation(annotation); - this.currentAnnotations[annotation] = value; - }, - removeAnnotation(annotation) { - this.checkAnnotation(annotation); - delete this.currentAnnotations[annotation]; - }, - checkAnnotation(annotation) { - for (let i in this.annotations) { - if (annotation == this.annotations[i]) { - return; - } - } - - throw Cr.NS_ERROR_INVALID_ARG; - }, - annotations: Object.assign({}, CrashReporter.annotations), - currentAnnotations: {}, -}; /** * Escapes any occurrences of &, ", < or > with XML entities. * * @param {string} str * The string to escape. * @return {string} The escaped string. */ @@ -610,16 +581,17 @@ var AddonTestUtils = { if (error !== undefined) throw error; return result; }, createAppInfo(ID, name, version, platformVersion = "1.0") { AppInfo.updateAppInfo({ ID, name, version, platformVersion, + crashReporter: true, extraProps: { browserTabsRemoteAutostart: false, }, }); this.appInfo = AppInfo.getAppInfo(); }, getManifestURI(file) { @@ -776,17 +748,16 @@ var AddonTestUtils = { if (Cu.isModuleLoaded("resource://gre/modules/Blocklist.jsm")) { let bsPassBlocklist = ChromeUtils.import("resource://gre/modules/Blocklist.jsm", {}); Object.defineProperty(bsPassBlocklist, "gAppVersion", {value: newVersion}); } } let XPIScope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", null); XPIScope.AsyncShutdown = MockAsyncShutdown; - XPIScope.CrashReporter = MockCrashReporter; XPIScope.XPIInternal.BootstrapScope.prototype ._beforeCallBootstrapMethod = (method, params, reason) => { try { this.emit("bootstrap-method", {method, params, reason}); } catch (e) { try { this.testScope.do_throw(e); @@ -834,17 +805,17 @@ var AddonTestUtils = { // Flush the jar cache entries for each bootstrapped XPI so that // we don't run into file locking issues on Windows. for (let file of this.addonsList.xpis) { Services.obs.notifyObservers(file, "flush-cache-entry"); } // Clear any crash report annotations - MockCrashReporter.currentAnnotations = {}; + this.appInfo.annotations = {}; // Force the XPIProvider provider to reload to better // simulate real-world usage. let XPIscope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); // This would be cleaner if I could get it as the rejection reason from // the AddonManagerInternal.shutdown() promise let shutdownError = XPIscope.XPIDatabase._saveError;
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -23,17 +23,16 @@ var EXPORTED_SYMBOLS = ["XPIProvider", " ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/AddonManager.jsm"); XPCOMUtils.defineLazyModuleGetters(this, { AppConstants: "resource://gre/modules/AppConstants.jsm", AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm", - CrashReporter: "resource://gre/modules/CrashReporter.jsm", Dictionary: "resource://gre/modules/Extension.jsm", Extension: "resource://gre/modules/Extension.jsm", Langpack: "resource://gre/modules/Extension.jsm", FileUtils: "resource://gre/modules/FileUtils.jsm", OS: "resource://gre/modules/osfile.jsm", ConsoleAPI: "resource://gre/modules/Console.jsm", JSONFile: "resource://gre/modules/JSONFile.jsm", LegacyExtensionsUtils: "resource://gre/modules/LegacyExtensionsUtils.jsm", @@ -2120,19 +2119,18 @@ var XPIProvider = { Services.obs.notifyObservers(null, "startupcache-invalidate"); } AddonManagerPrivate.markProviderSafe(this); if (AppConstants.MOZ_CRASHREPORTER) { // Annotate the crash report with relevant add-on information. try { - CrashReporter.addAnnotation( - CrashReporter.annotations.EMCheckCompatibility, - AddonManager.checkCompatibility); + Services.appinfo.annotateCrashReport("EMCheckCompatibility", + AddonManager.checkCompatibility); } catch (e) { } this.addAddonsToCrashReporter(); } try { AddonManagerPrivate.recordTimestamp("XPI_bootstrap_addons_begin"); for (let addon of this.sortBootstrappedAddons()) { @@ -2312,24 +2310,25 @@ var XPIProvider = { } return Promise.all(promises); }, /** * Adds a list of currently active add-ons to the next crash report. */ addAddonsToCrashReporter() { - if (Services.appinfo.inSafeMode) { + if (!(Services.appinfo instanceof Ci.nsICrashReporter) || + Services.appinfo.inSafeMode) { return; } let data = Array.from(XPIStates.enabledAddons(), a => a.telemetryKey).join(","); try { - CrashReporter.addAnnotation(CrashReporter.annotations.Addons, data); + Services.appinfo.annotateCrashReport("Add-ons", data); } catch (e) { } TelemetrySession.setAddOns(data); }, /** * Check the staging directories of install locations for any add-ons to be * installed or add-ons to be uninstalled.
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js +++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js @@ -51,18 +51,16 @@ ChromeUtils.defineModuleGetter(this, "Ex ChromeUtils.defineModuleGetter(this, "ExtensionTestUtils", "resource://testing-common/ExtensionXPCShellUtils.jsm"); ChromeUtils.defineModuleGetter(this, "ExtensionTestCommon", "resource://testing-common/ExtensionTestCommon.jsm"); ChromeUtils.defineModuleGetter(this, "HttpServer", "resource://testing-common/httpd.js"); ChromeUtils.defineModuleGetter(this, "MockAsyncShutdown", "resource://testing-common/AddonTestUtils.jsm"); -ChromeUtils.defineModuleGetter(this, "MockCrashReporter", - "resource://testing-common/AddonTestUtils.jsm"); ChromeUtils.defineModuleGetter(this, "MockRegistrar", "resource://testing-common/MockRegistrar.jsm"); ChromeUtils.defineModuleGetter(this, "MockRegistry", "resource://testing-common/MockRegistry.jsm"); ChromeUtils.defineModuleGetter(this, "PromiseTestUtils", "resource://testing-common/PromiseTestUtils.jsm"); ChromeUtils.defineModuleGetter(this, "TestUtils", "resource://testing-common/TestUtils.jsm"); @@ -574,24 +572,22 @@ function checkAddon(id, addon, expected) * @param aVersion * The version of the add-on */ function do_check_in_crash_annotation(aId, aVersion) { if (!AppConstants.MOZ_CRASHREPORTER) { return; } - const annotation = MockCrashReporter.annotations.Addons; - - if (!(annotation in MockCrashReporter.currentAnnotations)) { + if (!("Add-ons" in gAppInfo.annotations)) { Assert.equal(false, true); return; } - let addons = MockCrashReporter.currentAnnotations[annotation].split(","); + let addons = gAppInfo.annotations["Add-ons"].split(","); Assert.ok(addons.includes(`${encodeURIComponent(aId)}:${encodeURIComponent(aVersion)}`)); } /** * Tests that an add-on does not appear in the crash report annotations, if * crash reporting is enabled. The test will fail if the add-on is in the * annotation. * @param aId @@ -599,24 +595,22 @@ function do_check_in_crash_annotation(aI * @param aVersion * The version of the add-on */ function do_check_not_in_crash_annotation(aId, aVersion) { if (!AppConstants.MOZ_CRASHREPORTER) { return; } - const annotation = MockCrashReporter.annotations.Addons; - - if (!(annotation in MockCrashReporter.currentAnnotations)) { + if (!("Add-ons" in gAppInfo.annotations)) { Assert.ok(true); return; } - let addons = MockCrashReporter.currentAnnotations[annotation].split(","); + let addons = gAppInfo.annotations["Add-ons"].split(","); Assert.ok(!addons.includes(`${encodeURIComponent(aId)}:${encodeURIComponent(aVersion)}`)); } function do_get_file_hash(aFile, aAlgorithm) { if (!aAlgorithm) aAlgorithm = "sha1"; let crypto = Cc["@mozilla.org/security/hash;1"].
--- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -263,23 +263,16 @@ char **gRestartArgv; // If gRestartedByOS is set, we were automatically restarted by the OS. bool gRestartedByOS = false; bool gIsGtest = false; nsString gAbsoluteArgv0Path; -// This should always be 0 and it's used to catch JavaScript invocations of -// nsICrashReporter.annotateCrashReporter() that are passed an undefined value. -// Since undefined values are translated into 0 we need to special-case it. -static const uint32_t kInvalidAnnotation = 0; -static const uint32_t kAnnotationCount = - static_cast<uint32_t>(CrashReporter::Annotation::Count); - #if defined(MOZ_WIDGET_GTK) #include <glib.h> #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) #define CLEANUP_MEMORY 1 #define PANGO_ENABLE_BACKEND #include <pango/pangofc-fontmap.h> #endif #include <gtk/gtk.h> @@ -1234,53 +1227,20 @@ nsXULAppInfo::GetExtraFileForID(const ns if (!CrashReporter::GetExtraFileForID(aId, aExtraFile)) { return NS_ERROR_FILE_NOT_FOUND; } return NS_OK; } NS_IMETHODIMP -nsXULAppInfo::AnnotateCrashReport(uint32_t key, +nsXULAppInfo::AnnotateCrashReport(const nsACString& key, const nsACString& data) { - if (key == kInvalidAnnotation || (key > kAnnotationCount)) { - return NS_ERROR_INVALID_ARG; - } - - return CrashReporter::AnnotateCrashReport( - static_cast<CrashReporter::Annotation>(key - 1), data); -} - -NS_IMETHODIMP -nsXULAppInfo::RemoveCrashReportAnnotation(uint32_t key) -{ - if (key == kInvalidAnnotation || (key > kAnnotationCount)) { - return NS_ERROR_INVALID_ARG; - } - - return CrashReporter::RemoveCrashReportAnnotation( - static_cast<CrashReporter::Annotation>(key - 1)); -} - -NS_IMETHODIMP -nsXULAppInfo::IsAnnotationWhitelistedForPing(const nsACString& aValue, - bool* aIsWhitelisted) -{ - nsAutoCString aValueStr(aValue); - CrashReporter::Annotation annotation; - - if (CrashReporter::AnnotationFromString(annotation, - PromiseFlatCString(aValue).get())) { - *aIsWhitelisted = CrashReporter::IsAnnotationWhitelistedForPing(annotation); - } else { - return NS_ERROR_INVALID_ARG; - } - - return NS_OK; + return CrashReporter::AnnotateCrashReport(key, data); } NS_IMETHODIMP nsXULAppInfo::AppendAppNotesToCrashReport(const nsACString& data) { return CrashReporter::AppendAppNotesToCrashReport(data); } @@ -3425,49 +3385,49 @@ XREMain::XRE_mainInit(bool* aExitFlag) rv = nsXREDirProvider::GetUserAppDataDirectory(getter_AddRefs(file)); if (NS_SUCCEEDED(rv)) { CrashReporter::SetUserAppDataDirectory(file); } if (mAppData->crashReporterURL) CrashReporter::SetServerURL(nsDependentCString(mAppData->crashReporterURL)); // We overwrite this once we finish starting up. - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StartupCrash, - true); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"), + NS_LITERAL_CSTRING("1")); // pass some basic info from the app data if (mAppData->vendor) - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Vendor, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Vendor"), nsDependentCString(mAppData->vendor)); if (mAppData->name) - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductName, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductName"), nsDependentCString(mAppData->name)); if (mAppData->ID) - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductID"), nsDependentCString(mAppData->ID)); if (mAppData->version) - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Version, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Version"), nsDependentCString(mAppData->version)); if (mAppData->buildID) - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::BuildID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BuildID"), nsDependentCString(mAppData->buildID)); nsDependentCString releaseChannel(NS_STRINGIFY(MOZ_UPDATE_CHANNEL)); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ReleaseChannel, releaseChannel); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"), + releaseChannel); #ifdef MOZ_LINKER - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::CrashAddressLikelyWrong, - IsSignalHandlingBroken()); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CrashAddressLikelyWrong"), + IsSignalHandlingBroken() ? NS_LITERAL_CSTRING("1") + : NS_LITERAL_CSTRING("0")); #endif #ifdef XP_WIN nsAutoString appInitDLLs; if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) { - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AppInitDLLs, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AppInitDLLs"), NS_ConvertUTF16toUTF8(appInitDLLs)); } #endif CrashReporter::SetRestartArgs(gArgc, gArgv); // annotate other data (user id etc) nsCOMPtr<nsIFile> userAppDataDir; @@ -3618,25 +3578,26 @@ XREMain::XRE_mainInit(bool* aExitFlag) cpuUpdateRevision = static_cast<int>(updateRevision[0]); break; } } } } if (cpuUpdateRevision > 0) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::CPUMicrocodeVersion, - nsPrintfCString("0x%x", cpuUpdateRevision)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CPUMicrocodeVersion"), + nsPrintfCString("0x%x", + cpuUpdateRevision)); } } #endif - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::SafeMode, - gSafeMode); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SafeMode"), + gSafeMode ? NS_LITERAL_CSTRING("1") : + NS_LITERAL_CSTRING("0")); // Handle --no-remote and --new-instance command line arguments. Setup // the environment to better accommodate other components and various // restart scenarios. ar = CheckArg("no-remote", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg); if (ar == ARG_BAD) { PR_fprintf(PR_STDERR, "Error: argument --no-remote is invalid when argument --osint is specified\n"); return 1; @@ -3749,19 +3710,18 @@ static void AnnotateSystemManufacturer() } VARIANT value; VariantInit(&value); hr = classObject->Get(L"Manufacturer", 0, &value, 0, 0); if (SUCCEEDED(hr) && V_VT(&value) == VT_BSTR) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::BIOS_Manufacturer, - NS_ConvertUTF16toUTF8(V_BSTR(&value))); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BIOS_Manufacturer"), + NS_ConvertUTF16toUTF8(V_BSTR(&value))); } VariantClear(&value); } static void PR_CALLBACK AnnotateSystemManufacturer_ThreadStart(void*) { HRESULT hr = CoInitialize(nullptr); @@ -4395,33 +4355,34 @@ void AddSandboxAnnotations() { // Include the sandbox content level, regardless of platform int level = GetEffectiveContentSandboxLevel(); nsAutoCString levelString; levelString.AppendInt(level); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ContentSandboxLevel, levelString); + NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString); // Include whether or not this instance is capable of content sandboxing bool sandboxCapable = false; #if defined(XP_WIN) // All supported Windows versions support some level of content sandboxing sandboxCapable = true; #elif defined(XP_MACOSX) // All supported OS X versions are capable sandboxCapable = true; #elif defined(XP_LINUX) sandboxCapable = SandboxInfo::Get().CanSandboxContent(); #endif CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ContentSandboxCapable, sandboxCapable); + NS_LITERAL_CSTRING("ContentSandboxCapable"), + sandboxCapable ? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0")); } #endif /* MOZ_CONTENT_SANDBOX */ /* * XRE_mainRun - Command line startup, profile migration, and * the calling of appStartup->Run(). */ nsresult @@ -4465,28 +4426,26 @@ XREMain::XRE_mainRun() if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIPrefBranch> defaultPrefBranch; rv = prefs->GetDefaultBranch(nullptr, getter_AddRefs(defaultPrefBranch)); if (NS_SUCCEEDED(rv)) { nsAutoCString sval; rv = defaultPrefBranch->GetCharPref("app.update.channel", sval); if (NS_SUCCEEDED(rv)) { - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ReleaseChannel, sval); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"), + sval); } } } // Needs to be set after xpcom initialization. - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::FramePoisonBase, - nsPrintfCString("%.16" PRIu64, uint64_t(gMozillaPoisonBase))); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::FramePoisonSize, - uint32_t(gMozillaPoisonSize)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonBase"), + nsPrintfCString("%.16" PRIu64, uint64_t(gMozillaPoisonBase))); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonSize"), + nsPrintfCString("%" PRIu32, uint32_t(gMozillaPoisonSize))); bool includeContextHeap = Preferences::GetBool("toolkit.crashreporter.include_context_heap", false); CrashReporter::SetIncludeContextHeap(includeContextHeap); #ifdef XP_WIN PR_CreateThread(PR_USER_THREAD, AnnotateSystemManufacturer_ThreadStart, 0, PR_PRIORITY_LOW, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); @@ -4635,18 +4594,17 @@ XREMain::XRE_mainRun() // As FilePreferences need the profile directory, we must initialize right here. mozilla::FilePreferences::InitDirectoriesWhitelist(); mozilla::FilePreferences::InitPrefs(); OverrideDefaultLocaleIfNeeded(); nsCString userAgentLocale; LocaleService::GetInstance()->GetAppLocaleAsLangTag(userAgentLocale); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::useragent_locale, userAgentLocale); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale); appStartup->GetShuttingDown(&mShuttingDown); nsCOMPtr<nsICommandLineRunner> cmdLine; nsCOMPtr<nsIFile> workingDir; rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir)); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); @@ -4732,18 +4690,18 @@ XREMain::XRE_mainRun() nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService(); if (obsService) obsService->NotifyObservers(nullptr, "final-ui-startup", nullptr); (void)appStartup->DoneStartingUp(); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StartupCrash, - false); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"), + NS_LITERAL_CSTRING("0")); appStartup->GetShuttingDown(&mShuttingDown); } if (!mShuttingDown) { rv = cmdLine->Run(); NS_ENSURE_SUCCESS_LOG(rv, NS_ERROR_FAILURE); @@ -4790,17 +4748,17 @@ XREMain::XRE_mainRun() Telemetry::Accumulate(Telemetry::SANDBOX_CONTENT_ENABLED, sandboxInfo.Test(SandboxInfo::kEnabledForContent)); Telemetry::Accumulate(Telemetry::SANDBOX_MEDIA_ENABLED, sandboxInfo.Test(SandboxInfo::kEnabledForMedia)); nsAutoCString flagsString; flagsString.AppendInt(sandboxInfo.AsInteger()); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ContentSandboxCapabilities, flagsString); + NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString); #endif /* MOZ_SANDBOX && XP_LINUX */ #if defined(MOZ_CONTENT_SANDBOX) AddSandboxAnnotations(); #endif /* MOZ_CONTENT_SANDBOX */ { rv = appStartup->Run();
--- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -320,18 +320,20 @@ SetTaskbarGroupId(const nsString& aId) #endif #if defined(MOZ_CONTENT_SANDBOX) void AddContentSandboxLevelAnnotation() { if (XRE_GetProcessType() == GeckoProcessType_Content) { int level = GetEffectiveContentSandboxLevel(); + nsAutoCString levelString; + levelString.AppendInt(level); CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::ContentSandboxLevel, level); + NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString); } } #endif /* MOZ_CONTENT_SANDBOX */ namespace { int GetDebugChildPauseTime() { auto pauseStr = PR_GetEnv("MOZ_DEBUG_CHILD_PAUSE");
--- a/widget/android/GfxInfo.cpp +++ b/widget/android/GfxInfo.cpp @@ -343,22 +343,29 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Ac { EnsureInitialized(); return NS_ERROR_FAILURE; } void GfxInfo::AddCrashReportAnnotations() { - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), mGLStrings->Vendor()); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), mGLStrings->Renderer()); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::AdapterDriverVersion, mGLStrings->Version()); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"), + mGLStrings->Version()); + + /* Add an App Note for now so that we get the data immediately. These + * can go away after we store the above in the socorro db */ + nsAutoCString note; + note.AppendPrintf("AdapterDescription: '%s'\n", mAdapterDescription.get()); + + CrashReporter::AppendAppNotesToCrashReport(note); } const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() { if (sDriverInfo->IsEmpty()) { APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Android, (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAll), GfxDriverInfo::allDevices,
--- a/widget/android/jni/Utils.cpp +++ b/widget/android/jni/Utils.cpp @@ -199,18 +199,18 @@ bool HandleUncaughtException(JNIEnv* aEn return true; } bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack) { bool result = true; result &= NS_SUCCEEDED(CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::JavaStackTrace, - String::Ref::From(aStack)->ToCString())); + NS_LITERAL_CSTRING("JavaStackTrace"), + String::Ref::From(aStack)->ToCString())); auto appNotes = java::GeckoAppShell::GetAppNotes(); if (NS_WARN_IF(aEnv->ExceptionCheck())) { aEnv->ExceptionDescribe(); aEnv->ExceptionClear(); } else if (appNotes) { CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("\n") + appNotes->ToCString());
--- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -4,21 +4,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsAppShell.h" #include "base/basictypes.h" #include "base/message_loop.h" #include "base/task.h" #include "mozilla/Hal.h" +#include "nsExceptionHandler.h" #include "nsIScreen.h" #include "nsIScreenManager.h" #include "nsWindow.h" #include "nsThreadUtils.h" #include "nsICommandLineRunner.h" +#include "nsICrashReporter.h" #include "nsIObserverService.h" #include "nsIAppStartup.h" #include "nsIGeolocationProvider.h" #include "nsCacheService.h" #include "nsIDOMEventListener.h" #include "nsIDOMWakeLockListener.h" #include "nsIPowerManagerService.h" #include "nsISpeculativeConnect.h"
--- a/widget/cocoa/GfxInfo.mm +++ b/widget/cocoa/GfxInfo.mm @@ -278,22 +278,31 @@ GfxInfo::AddCrashReportAnnotations() GetAdapterDeviceID(deviceID); CopyUTF16toUTF8(deviceID, narrowDeviceID); GetAdapterVendorID(vendorID); CopyUTF16toUTF8(vendorID, narrowVendorID); GetAdapterDriverVersion(driverVersion); CopyUTF16toUTF8(driverVersion, narrowDriverVersion); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), narrowVendorID); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), narrowDeviceID); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"), + narrowDriverVersion); + /* Add an App Note for now so that we get the data immediately. These + * can go away after we store the above in the socorro db */ + nsAutoCString note; + /* AppendPrintf only supports 32 character strings, mrghh. */ + note.AppendLiteral("AdapterVendorID: "); + note.Append(narrowVendorID); + note.AppendLiteral(", AdapterDeviceID: "); + note.Append(narrowDeviceID); + CrashReporter::AppendAppNotesToCrashReport(note); } // We don't support checking driver versions on Mac. #define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn, ruleId) \ APPEND_TO_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn, \ DRIVER_COMPARISON_IGNORED, V(0,0,0,0), ruleId, "")
--- a/widget/windows/GfxInfo.cpp +++ b/widget/windows/GfxInfo.cpp @@ -888,34 +888,45 @@ GfxInfo::AddCrashReportAnnotations() CopyUTF16toUTF8(deviceID, narrowDeviceID); GetAdapterVendorID(vendorID); CopyUTF16toUTF8(vendorID, narrowVendorID); GetAdapterDriverVersion(driverVersion); CopyUTF16toUTF8(driverVersion, narrowDriverVersion); GetAdapterSubsysID(subsysID); CopyUTF16toUTF8(subsysID, narrowSubsysID); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), narrowVendorID); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), narrowDeviceID); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterSubsysID, + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"), + narrowDriverVersion); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterSubsysID"), narrowSubsysID); - /* Add an App Note, this contains extra information. */ + /* Add an App Note for now so that we get the data immediately. These + * can go away after we store the above in the socorro db */ nsAutoCString note; + /* AppendPrintf only supports 32 character strings, mrghh. */ + note.AppendLiteral("AdapterVendorID: "); + note.Append(narrowVendorID); + note.AppendLiteral(", AdapterDeviceID: "); + note.Append(narrowDeviceID); + note.AppendLiteral(", AdapterSubsysID: "); + note.Append(narrowSubsysID); + note.AppendLiteral(", AdapterDriverVersion: "); + note.Append(NS_LossyConvertUTF16toASCII(driverVersion)); - // TODO: We should probably convert this into a proper annotation if (vendorID == GfxDriverInfo::GetDeviceVendor(VendorAll)) { /* if we didn't find a valid vendorID lets append the mDeviceID string to try to find out why */ + note.AppendLiteral(", "); LossyAppendUTF16toASCII(mDeviceID[mActiveGPUIndex], note); note.AppendLiteral(", "); LossyAppendUTF16toASCII(mDeviceKeyDebug, note); + LossyAppendUTF16toASCII(mDeviceKeyDebug, note); } note.AppendLiteral("\n"); if (mHasDualGPU) { nsString deviceID2, vendorID2, subsysID2; nsAutoString adapterDriverVersionString2; nsCString narrowDeviceID2, narrowVendorID2, narrowSubsysID2;
--- a/widget/windows/LSPAnnotator.cpp +++ b/widget/windows/LSPAnnotator.cpp @@ -39,18 +39,17 @@ public: void LSPAnnotationGatherer::Annotate() { nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1"); bool enabled; if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) { - cr->AnnotateCrashReport( - static_cast<uint32_t>(CrashReporter::Annotation::Winsock_LSP), mString); + cr->AnnotateCrashReport(NS_LITERAL_CSTRING("Winsock_LSP"), mString); } mThread->AsyncShutdown(); } NS_IMETHODIMP LSPAnnotationGatherer::Run() { NS_SetCurrentThreadName("LSP Annotator");
--- a/xpcom/base/AvailableMemoryTracker.cpp +++ b/xpcom/base/AvailableMemoryTracker.cpp @@ -5,16 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/AvailableMemoryTracker.h" #if defined(XP_WIN) #include "nsExceptionHandler.h" #include "nsIMemoryReporter.h" #include "nsMemoryPressure.h" +#include "nsPrintfCString.h" #endif #include "nsIObserver.h" #include "nsIObserverService.h" #include "nsIRunnable.h" #include "nsISupports.h" #include "nsITimer.h" #include "nsThreadUtils.h" @@ -145,18 +146,18 @@ nsAvailableMemoryWatcher::IsVirtualMemor /* static */ bool nsAvailableMemoryWatcher::IsCommitSpaceLow(const MEMORYSTATUSEX& aStat) { if ((kLowCommitSpaceThreshold != 0) && (aStat.ullAvailPageFile < kLowCommitSpaceThreshold)) { sNumLowCommitSpaceEvents++; CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::LowCommitSpaceEvents, - uint32_t(sNumLowCommitSpaceEvents)); + NS_LITERAL_CSTRING("LowCommitSpaceEvents"), + nsPrintfCString("%" PRIu32, uint32_t(sNumLowCommitSpaceEvents))); return true; } return false; } /* static */ bool nsAvailableMemoryWatcher::IsPhysicalMemoryLow(const MEMORYSTATUSEX& aStat)
--- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -1468,45 +1468,29 @@ CycleCollectedJSRuntime::FinalizeDeferre if (aType == CycleCollectedJSContext::FinalizeIncrementally) { NS_IdleDispatchToCurrentThread(do_AddRef(mFinalizeRunnable), 2500); } else { mFinalizeRunnable->ReleaseNow(false); MOZ_ASSERT(!mFinalizeRunnable); } } -const char* -CycleCollectedJSRuntime::OOMStateToString(const OOMState aOomState) const -{ - switch (aOomState) { - case OOMState::OK: - return "OK"; - case OOMState::Reporting: - return "Reporting"; - case OOMState::Reported: - return "Reported"; - case OOMState::Recovered: - return "Recovered"; - default: - MOZ_ASSERT_UNREACHABLE("OOMState holds an invalid value"); - return "Unknown"; - } -} - void CycleCollectedJSRuntime::AnnotateAndSetOutOfMemory(OOMState* aStatePtr, OOMState aNewState) { *aStatePtr = aNewState; - CrashReporter::Annotation annotation = (aStatePtr == &mOutOfMemoryState) - ? CrashReporter::Annotation::JSOutOfMemory - : CrashReporter::Annotation::JSLargeAllocationFailure; - - CrashReporter::AnnotateCrashReport( - annotation, nsDependentCString(OOMStateToString(aNewState))); + CrashReporter::AnnotateCrashReport(aStatePtr == &mOutOfMemoryState + ? NS_LITERAL_CSTRING("JSOutOfMemory") + : NS_LITERAL_CSTRING("JSLargeAllocationFailure"), + aNewState == OOMState::Reporting + ? NS_LITERAL_CSTRING("Reporting") + : aNewState == OOMState::Reported + ? NS_LITERAL_CSTRING("Reported") + : NS_LITERAL_CSTRING("Recovered")); } void CycleCollectedJSRuntime::OnGC(JSContext* aContext, JSGCStatus aStatus) { switch (aStatus) { case JSGC_BEGIN:
--- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -232,18 +232,16 @@ public: // The condition has happened, but a GC cycle ended since then. // // GC is taken as a proxy for "we've been banging on the heap a good bit // now and haven't crashed; the OOM was probably handled correctly". Recovered }; - const char* OOMStateToString(const OOMState aOomState) const; - void SetLargeAllocationFailure(OOMState aNewState); void AnnotateAndSetOutOfMemory(OOMState* aStatePtr, OOMState aNewState); void OnGC(JSContext* aContext, JSGCStatus aStatus); void OnOutOfMemory(); void OnLargeAllocationFailure(); JSRuntime* Runtime() { return mJSRuntime; }
--- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -670,18 +670,17 @@ PtrInfo::AnnotatedReleaseAssert(bool aCo return; } const char* piName = "Unknown"; if (mParticipant) { piName = mParticipant->ClassName(); } nsPrintfCString msg("%s, for class %s", aMessage, piName); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::CycleCollector, - msg); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CycleCollector"), msg); MOZ_CRASH(); } /** * A structure designed to be used like a linked list of PtrInfo, except * it allocates many PtrInfos at a time. */
--- a/xpcom/base/nsDebugImpl.cpp +++ b/xpcom/base/nsDebugImpl.cpp @@ -404,19 +404,18 @@ NS_DebugBreak(uint32_t aSeverity, const // have to do without the annotations in that case. if (XRE_IsParentProcess()) { // Don't include the PID in the crash report annotation to // allow faceting on crash-stats.mozilla.org. nsCString note("xpcom_runtime_abort("); note += nonPIDBuf.buffer; note += ")"; CrashReporter::AppendAppNotesToCrashReport(note); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::AbortMessage, - nsDependentCString(nonPIDBuf.buffer)); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AbortMessage"), + nsDependentCString(nonPIDBuf.buffer)); } #if defined(DEBUG) && defined(_WIN32) RealBreak(); #endif #if defined(DEBUG) nsTraceRefcnt::WalkTheStack(stderr); #endif
--- a/xpcom/system/nsICrashReporter.idl +++ b/xpcom/system/nsICrashReporter.idl @@ -71,49 +71,26 @@ interface nsICrashReporter : nsISupports * @throw NS_ERROR_FILE_NOT_FOUND if the extra file could not be found */ nsIFile getExtraFileForID(in AString id); /** * Add some extra data to be submitted with a crash report. * * @param key - * One of the crash annotation constants. + * Name of the data to be added. * @param data * Data to be added. * * @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized - * @throw NS_ERROR_INVALID_ARG if key contains an invalid value or data - * contains invalid characters. Invalid - * character for data is '\0'. + * @throw NS_ERROR_INVALID_ARG if key or data contain invalid characters. + * Invalid characters for key are '=' and + * '\n'. Invalid character for data is '\0'. */ - void annotateCrashReport(in unsigned long key, in AUTF8String data); - - /** - * Remove a crash report annotation. - * - * @param key - * One of the crash annotation constants. - * - * @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized - * @throw NS_ERROR_INVALID_ARG if key contains an invalid value. - */ - void removeCrashReportAnnotation(in unsigned long key); - - /** - * Checks if an annotation is whitelisted for inclusion in the crash ping. - * - * @param key - * One of the crash annotation strings. - * - * @return True if the specified value is a valid annotation and can be - included in the crash ping, false otherwise. - * @throw NS_ERROR_INVALID_ARG if key contains an invalid value. - */ - boolean isAnnotationWhitelistedForPing(in ACString value); + void annotateCrashReport(in AUTF8String key, in AUTF8String data); /** * Append some data to the "Notes" field, to be submitted with a crash report. * Unlike annotateCrashReport, this method will append to existing data. * * @param data * Data to be added. * @@ -139,17 +116,17 @@ interface nsICrashReporter : nsISupports /** * Write a minidump immediately, with the user-supplied exception * information. This is implemented on Windows only, because * SEH (structured exception handling) exists on Windows only. * * @param aExceptionInfo EXCEPTION_INFO* provided by Window's SEH */ [noscript] void writeMinidumpForException(in voidPtr aExceptionInfo); - + /** * Append note containing an Obj-C exception's info. * * @param aException NSException object to append note for */ [noscript] void appendObjCExceptionInfoToAppNotes(in voidPtr aException); /**