Bug 1269961 - Collect more telemetry on content process crashes (r=jimm,mconley)
authorBill McCloskey <billm@mozilla.com>
Tue, 03 May 2016 20:08:41 -0700
changeset 296178 3a9efc13a56c50c390f7db2481b585ffe78269ec
parent 296177 e930d26502a6cae04fe86939637d0348a86fcf10
child 296179 40745bcb866ff190c40d9a58cb3006a1c58031ba
push id30233
push userryanvm@gmail.com
push dateThu, 05 May 2016 18:57:26 +0000
treeherdermozilla-central@0177462aac74 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, mconley
bugs1269961
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1269961 - Collect more telemetry on content process crashes (r=jimm,mconley)
browser/modules/ContentCrashHandlers.jsm
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
toolkit/components/telemetry/Histograms.json
--- a/browser/modules/ContentCrashHandlers.jsm
+++ b/browser/modules/ContentCrashHandlers.jsm
@@ -146,16 +146,17 @@ this.TabCrashHandler = {
     let browser = message.target.browser;
 
     let childID = this.browserMap.get(browser.permanentKey);
     let dumpID = this.childMap.get(childID);
     if (!dumpID)
       return
 
     if (!message.data.sendReport) {
+      Services.telemetry.getHistogramById("FX_CONTENT_CRASH_NOT_SUBMITTED").add(1);
       this.prefs.setBoolPref("sendReport", false);
       return;
     }
 
     let {
       includeURL,
       comments,
       email,
@@ -241,49 +242,70 @@ this.TabCrashHandler = {
     this.pageListener.sendAsyncMessage("UpdateCount", {
       count: this._crashedTabCount,
     });
 
     let browser = message.target.browser;
 
     let dumpID = this.getDumpID(browser);
     if (!dumpID) {
+      // Make sure to only count once even if there are multiple windows
+      // that will all show about:tabcrashed.
+      if (this._crashedTabCount == 1) {
+        Services.telemetry.getHistogramById("FX_CONTENT_CRASH_DUMP_UNAVAILABLE").add(1);
+      }
+
       message.target.sendAsyncMessage("SetCrashReportAvailable", {
         hasReport: false,
       });
       return;
     }
 
     let sendReport = this.prefs.getBoolPref("sendReport");
     let includeURL = this.prefs.getBoolPref("includeURL");
     let emailMe = this.prefs.getBoolPref("emailMe");
 
     let data = { hasReport: true, sendReport, includeURL, emailMe };
     if (emailMe) {
       data.email = this.prefs.getCharPref("email", "");
     }
 
+    // Make sure to only count once even if there are multiple windows
+    // that will all show about:tabcrashed.
+    if (this._crashedTabCount == 1) {
+      Services.telemetry.getHistogramById("FX_CONTENT_CRASH_PRESENTED").add(1);
+    }
+
     message.target.sendAsyncMessage("SetCrashReportAvailable", data);
   },
 
-  onAboutTabCrashedUnload: function() {
+  onAboutTabCrashedUnload(message) {
     if (!this._crashedTabCount) {
       Cu.reportError("Can not decrement crashed tab count to below 0");
       return;
     }
     this._crashedTabCount--;
 
     // Broadcast to all about:tabcrashed pages a count of
     // how many about:tabcrashed pages exist, so that they
     // can decide whether or not to display the "Restore All
     // Crashed Tabs" button.
     this.pageListener.sendAsyncMessage("UpdateCount", {
       count: this._crashedTabCount,
     });
-  },
+
+    let browser = message.target.browser;
+    let childID = this.browserMap.get(browser.permanentKey);
+
+    // Make sure to only count once even if there are multiple windows
+    // that will all show about:tabcrashed.
+    if (this._crashedTabCount == 0 && childID) {
+      Services.telemetry.getHistogramById("FX_CONTENT_CRASH_NOT_SUBMITTED").add(1);
+    }
+},
 
   /**
    * For some <xul:browser>, return a crash report dump ID for that browser
    * if we have been informed of one. Otherwise, return null.
    *
    * @param browser (<xul:browser)
    *        The browser to try to get the dump ID for
    * @returns dumpID (String)
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3540,16 +3540,18 @@ ContentParent::ForceKillTimerCallback(ns
   if (PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
     return;
   }
 
   auto self = static_cast<ContentParent*>(aClosure);
   self->KillHard("ShutDownKill");
 }
 
+// WARNING: aReason appears in telemetry, so any new value passed in requires
+// data review.
 void
 ContentParent::KillHard(const char* aReason)
 {
   PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
 
   // On Windows, calling KillHard multiple times causes problems - the
   // process handle becomes invalid on the first call, causing a second call
   // to crash our process - more details in bug 890840.
@@ -3570,28 +3572,25 @@ ContentParent::KillHard(const char* aRea
     // 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");
     crashReporter->AnnotateCrashReport(
       NS_LITERAL_CSTRING("additional_minidumps"),
       additionalDumps);
-    if (IsKillHardAnnotationSet()) {
-      crashReporter->AnnotateCrashReport(
-        NS_LITERAL_CSTRING("kill_hard"),
-        GetKillHardAnnotation());
-    }
     nsDependentCString reason(aReason);
     crashReporter->AnnotateCrashReport(
       NS_LITERAL_CSTRING("ipc_channel_error"),
       reason);
 
     // Generate the report and insert into the queue for submittal.
     mCreatedPairedMinidumps = crashReporter->GenerateCompleteMinidump(this);
+
+    Telemetry::Accumulate(Telemetry::SUBPROCESS_KILL_HARD, reason, 1);
   }
 #endif
   ProcessHandle otherProcessHandle;
   if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle)) {
     NS_ERROR("Failed to open child process when attempting kill.");
     return;
   }
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -335,32 +335,22 @@ public:
   {
     return mSendPermissionUpdates;
   }
 
   /**
    * Kill our subprocess and make sure it dies.  Should only be used
    * in emergency situations since it bypasses the normal shutdown
    * process.
+   *
+   * WARNING: aReason appears in telemetry, so any new value passed in requires
+   * data review.
    */
   void KillHard(const char* aWhy);
 
-  /**
-   * API for adding a crash reporter annotation that provides a reason
-   * for a listener request to abort the child.
-   */
-  bool IsKillHardAnnotationSet() const { return mKillHardAnnotation.IsEmpty(); }
-
-  const nsCString& GetKillHardAnnotation() const { return mKillHardAnnotation; }
-
-  void SetKillHardAnnotation(const nsACString& aReason)
-  {
-    mKillHardAnnotation = aReason;
-  }
-
   ContentParentId ChildID() const override { return mChildID; }
 
   const nsString& AppManifestURL() const { return mAppManifestURL; }
 
   bool IsPreallocated() const;
 
   /**
    * Get a user-friendly name for this ContentParent.  We make no guarantees
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -10628,10 +10628,43 @@
     "alert_emails": ["amarchesini@mozilla.com", "khuey@mozilla.com" ],
     "bug_numbers": [1267904],
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 5000,
     "n_buckets": 20,
     "keyed": true,
     "description": "Tracking how long a Worker thread is blocked when a sync operation is executed on the main-thread."
+  },
+  "SUBPROCESS_KILL_HARD": {
+    "alert_emails": ["wmccloskey@mozilla.com"],
+    "bug_numbers": [1269961],
+    "expires_in_version": "never",
+    "kind": "count",
+    "keyed": true,
+    "releaseChannelCollection": "opt-out",
+    "description": "Counts the number of times a subprocess was forcibly killed, and the reason."
+  },
+  "FX_CONTENT_CRASH_DUMP_UNAVAILABLE": {
+    "alert_emails": ["wmccloskey@mozilla.com"],
+    "bug_numbers": [1269961],
+    "expires_in_version": "never",
+    "kind": "count",
+    "releaseChannelCollection": "opt-out",
+    "description": "Counts the number of times that about:tabcrashed was unable to find a crash dump."
+  },
+  "FX_CONTENT_CRASH_PRESENTED": {
+    "alert_emails": ["wmccloskey@mozilla.com"],
+    "bug_numbers": [1269961],
+    "expires_in_version": "never",
+    "kind": "count",
+    "releaseChannelCollection": "opt-out",
+    "description": "Counts the number of times that about:tabcrashed appeared and found a crash dump."
+  },
+  "FX_CONTENT_CRASH_NOT_SUBMITTED": {
+    "alert_emails": ["wmccloskey@mozilla.com"],
+    "bug_numbers": [1269961],
+    "expires_in_version": "never",
+    "kind": "count",
+    "releaseChannelCollection": "opt-out",
+    "description": "Counts the number of times that about:tabcrashed was unloaded without submitting."
   }
 }