Bug 1385316 - Include remoteType in BHR ping, r=froydnj
authorMichael Layzell <michael@thelayzells.com>
Mon, 28 Aug 2017 13:24:48 -0400
changeset 377817 c3d8dd7cc1916f94e407b5af732933226b02e565
parent 377816 bb381b8be26fd9d5949c6661820d31f20cdab237
child 377818 5f6ae84f80cb56c071d9a9e5d8e07621ac1d8fe1
push id50043
push userkwierso@gmail.com
push dateThu, 31 Aug 2017 03:03:23 +0000
treeherderautoland@04b6be50a252 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1385316
milestone57.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 1385316 - Include remoteType in BHR ping, r=froydnj
toolkit/components/backgroundhangmonitor/BHRTelemetryService.js
toolkit/components/backgroundhangmonitor/HangDetails.cpp
toolkit/components/backgroundhangmonitor/HangDetails.h
toolkit/components/backgroundhangmonitor/nsIHangDetails.idl
toolkit/components/telemetry/docs/data/backgroundhangmonitor-ping.rst
toolkit/components/telemetry/docs/data/crash-ping.rst
--- a/toolkit/components/backgroundhangmonitor/BHRTelemetryService.js
+++ b/toolkit/components/backgroundhangmonitor/BHRTelemetryService.js
@@ -32,17 +32,17 @@ BHRTelemetryService.prototype = Object.f
     this.startTime = +new Date();
     this.payload = {
       modules: [],
       hangs: [],
     };
   },
 
   recordHang({duration, thread, runnableName, process, stack,
-              modules, annotations}) {
+              remoteType, modules, annotations}) {
     if (!Services.telemetry.canRecordExtended) {
       return;
     }
 
     // Create a mapping from module indicies in the original nsIHangDetails
     // object to this.payload.modules indicies.
     let moduleIdxs = modules.map(module => {
       let idx = this.payload.modules.findIndex(m => {
@@ -64,16 +64,17 @@ BHRTelemetryService.prototype = Object.f
     }
 
     // Create the hang object to record in the payload.
     this.payload.hangs.push({
       duration,
       thread,
       runnableName,
       process,
+      remoteType,
       annotations,
       stack,
     });
 
     // If we have collected enough hangs, we can submit the hangs we have
     // collected to telemetry.
     if (this.payload.hangs.length > this.TRANSMIT_HANG_COUNT) {
       this.submit();
--- a/toolkit/components/backgroundhangmonitor/HangDetails.cpp
+++ b/toolkit/components/backgroundhangmonitor/HangDetails.cpp
@@ -32,16 +32,23 @@ nsHangDetails::GetRunnableName(nsACStrin
 NS_IMETHODIMP
 nsHangDetails::GetProcess(nsACString& aName)
 {
   aName.AssignASCII(XRE_ChildProcessTypeToString(mDetails.mProcess));
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsHangDetails::GetRemoteType(nsAString& aName)
+{
+  aName.Assign(mDetails.mRemoteType);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsHangDetails::GetAnnotations(JSContext* aCx, JS::MutableHandleValue aVal)
 {
   // We create an object with { "key" : "value" } string pairs for each item in
   // our annotations object.
   JS::RootedObject jsAnnotation(aCx, JS_NewPlainObject(aCx));
   if (!jsAnnotation) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
@@ -192,16 +199,17 @@ nsHangDetails::Submit()
     //
     // In child processes, we report the hang to our parent process, while if
     // we're in the parent process, we report a bhr-thread-hang observer
     // notification.
     switch (XRE_GetProcessType()) {
     case GeckoProcessType_Content: {
       auto cc = dom::ContentChild::GetSingleton();
       if (cc) {
+        hangDetails->mDetails.mRemoteType.Assign(cc->GetRemoteType());
         Unused << cc->SendBHRThreadHang(hangDetails->mDetails);
       }
       break;
     }
     case GeckoProcessType_GPU: {
       auto gp = gfx::GPUParent::GetSingleton();
       if (gp) {
         Unused << gp->SendBHRThreadHang(hangDetails->mDetails);
@@ -251,16 +259,17 @@ ProcessHangStackRunnable::Run()
  */
 namespace IPC {
 
 void
 ParamTraits<mozilla::HangDetails>::Write(Message* aMsg, const mozilla::HangDetails& aParam)
 {
   WriteParam(aMsg, aParam.mDuration);
   WriteParam(aMsg, aParam.mProcess);
+  WriteParam(aMsg, aParam.mRemoteType);
   WriteParam(aMsg, aParam.mThreadName);
   WriteParam(aMsg, aParam.mRunnableName);
   WriteParam(aMsg, aParam.mStack);
   WriteParam(aMsg, aParam.mAnnotations);
 }
 
 bool
 ParamTraits<mozilla::HangDetails>::Read(const Message* aMsg,
@@ -268,16 +277,19 @@ ParamTraits<mozilla::HangDetails>::Read(
                                         mozilla::HangDetails* aResult)
 {
   if (!ReadParam(aMsg, aIter, &aResult->mDuration)) {
     return false;
   }
   if (!ReadParam(aMsg, aIter, &aResult->mProcess)) {
     return false;
   }
+  if (!ReadParam(aMsg, aIter, &aResult->mRemoteType)) {
+    return false;
+  }
   if (!ReadParam(aMsg, aIter, &aResult->mThreadName)) {
     return false;
   }
   if (!ReadParam(aMsg, aIter, &aResult->mRunnableName)) {
     return false;
   }
   if (!ReadParam(aMsg, aIter, &aResult->mStack)) {
     return false;
--- a/toolkit/components/backgroundhangmonitor/HangDetails.h
+++ b/toolkit/components/backgroundhangmonitor/HangDetails.h
@@ -27,36 +27,41 @@ namespace mozilla {
  * XPCOM interface which is harder to serialize over IPC.
  */
 class HangDetails
 {
 public:
   HangDetails()
     : mDuration(0)
     , mProcess(GeckoProcessType_Invalid)
+    , mRemoteType(NullString())
   {}
 
   HangDetails(const HangDetails& aOther) = default;
   HangDetails(HangDetails&& aOther) = default;
   HangDetails(uint32_t aDuration,
               GeckoProcessType aProcess,
               const nsACString& aThreadName,
               const nsACString& aRunnableName,
               HangStack&& aStack,
               HangMonitor::HangAnnotations&& aAnnotations)
     : mDuration(aDuration)
     , mProcess(aProcess)
+    , mRemoteType(NullString())
     , mThreadName(aThreadName)
     , mRunnableName(aRunnableName)
     , mStack(Move(aStack))
     , mAnnotations(Move(aAnnotations))
   {}
 
   uint32_t mDuration;
   GeckoProcessType mProcess;
+  // NOTE: mRemoteType is set in nsHangDetails::Submit before the HangDetails
+  // object is sent to the parent process.
+  nsString mRemoteType;
   nsCString mThreadName;
   nsCString mRunnableName;
   HangStack mStack;
   HangMonitor::HangAnnotations mAnnotations;
 };
 
 /**
  * HangDetails is the concrete implementaion of nsIHangDetails, and contains the
--- a/toolkit/components/backgroundhangmonitor/nsIHangDetails.idl
+++ b/toolkit/components/backgroundhangmonitor/nsIHangDetails.idl
@@ -37,16 +37,21 @@ interface nsIHangDetails : nsISupports
 
   /**
    * The type of process which produced the hang. This should be either:
    * "default", "content", or "gpu".
    */
   readonly attribute ACString process;
 
   /**
+   * The remote type of the content process which produced the hang.
+   */
+  readonly attribute AString remoteType;
+
+  /**
    * Returns the stack which was captured by BHR. The offset is encoded as a hex
    * string, as it can contain numbers larger than JS can hold losslessly.
    *
    * This value takes the following form:
    * [ [moduleIndex, offset], ... ]
    */
   [implicit_jscontext] readonly attribute jsval stack;
 
--- a/toolkit/components/telemetry/docs/data/backgroundhangmonitor-ping.rst
+++ b/toolkit/components/telemetry/docs/data/backgroundhangmonitor-ping.rst
@@ -29,16 +29,17 @@ Structure:
         ],
         "hangs": [
           {
             "duration": <number>, // duration of the hang in milliseconds.
             "thread": <string>, // name of the hanging thread.
             "runnableName": <string>, // name of the runnable executing during the hang.
                                       // Runnable names are only collected for the XPCOM main thread.
             "process": <string>, // Type of process that hung, see below for a list of types.
+            "remoteType": <string>, // Remote type of process which hung, see below.
             "annotations": { ... }, // A set of annotations on the hang, see below.
             "pseudoStack": [ ... ], // List of pseudostack frame names.
             "stack": [ ... ], // interleaved hang stack, see below.
           },
           ...
         ]
       }
     }
@@ -58,16 +59,25 @@ are currently sent only for the processe
 +===============+===================================================+
 | default       | Main process, also known as the browser process   |
 +---------------+---------------------------------------------------+
 | tab           | Content process                                   |
 +---------------+---------------------------------------------------+
 | gpu           | GPU process                                       |
 +---------------+---------------------------------------------------+
 
+Remote Type
+-----------
+
+The ``remoteType`` field is a string denoting the type of content process that
+hung. As such it is only non-null if ``processType`` contains the ``tab`` value.
+
+The supported ``remoteType`` values are documented in the crash ping
+documentation: :ref:`remote-process-types`.
+
 Stack Traces
 ------------
 
 Each hang object contains a ``stack`` field which has been populated with an
 interleaved stack trace of the hung thread. An interleaved stack consists of a
 native backtrace with additional frames interleaved, representing chrome JS and
 pseudostack entries.
 
--- a/toolkit/components/telemetry/docs/data/crash-ping.rst
+++ b/toolkit/components/telemetry/docs/data/crash-ping.rst
@@ -90,16 +90,18 @@ are sent only for the ones below:
 +===============+===================================================+
 | main          | Main process, also known as the browser process   |
 +---------------+---------------------------------------------------+
 | content       | Content process                                   |
 +---------------+---------------------------------------------------+
 | gpu           | GPU process                                       |
 +---------------+---------------------------------------------------+
 
+.. _remote-process-types:
+
 Remote Process Types
 --------------------
 
 The optional ``remoteType`` field contains the type of the content process that
 crashed. As such it is present only if ``processType`` contains the ``content``
 value. The following content process types are currently defined:
 
 +-----------+--------------------------------------------------------+