Bug 1605209 - Annotate JSWindowActor's message exchanges to determine which actor is on the stack of a crash;r=gsvelto,nika
☠☠ backed out by 6daca7282599 ☠ ☠
authorDavid Teller <dteller@mozilla.com>
Thu, 16 Apr 2020 08:27:01 +0000
changeset 524567 289f5bbac1ae08e5e1885de44ad85922258b3122
parent 524566 aaa6e44260125781accde50de4db5aeefeb3011b
child 524568 e0e6dbf1d48da58434c44c3a218a46635e95c6b9
push id37323
push userdluca@mozilla.com
push dateFri, 17 Apr 2020 16:25:55 +0000
treeherdermozilla-central@b4b1d6f91ef0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgsvelto, nika
bugs1605209
milestone77.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 1605209 - Annotate JSWindowActor's message exchanges to determine which actor is on the stack of a crash;r=gsvelto,nika Differential Revision: https://phabricator.services.mozilla.com/D69993
dom/ipc/JSWindowActor.cpp
dom/ipc/JSWindowActor.h
toolkit/crashreporter/CrashAnnotations.yaml
--- a/dom/ipc/JSWindowActor.cpp
+++ b/dom/ipc/JSWindowActor.cpp
@@ -2,27 +2,29 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "mozilla/dom/JSWindowActor.h"
 #include "mozilla/dom/JSWindowActorBinding.h"
 
+#include "mozilla/Attributes.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/ClonedErrorHolder.h"
 #include "mozilla/dom/ClonedErrorHolderBinding.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/DOMExceptionBinding.h"
 #include "mozilla/dom/MessageManagerBinding.h"
 #include "mozilla/dom/PWindowGlobal.h"
 #include "mozilla/dom/Promise.h"
 #include "js/Promise.h"
 #include "xpcprivate.h"
 #include "nsASCIIMask.h"
+#include "nsICrashReporter.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSWindowActor)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
@@ -42,21 +44,49 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWrappedJS)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingQueries)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(JSWindowActor)
 
 JSWindowActor::JSWindowActor() : mNextQueryId(0) {}
 
+// RAII class to ensure that, if we crash while handling a message, the
+// crash will be annotated with the name of the actor and the message.
+struct MOZ_RAII AutoAnnotateMessageInCaseOfCrash {
+  AutoAnnotateMessageInCaseOfCrash(const nsCString& aActorName,
+                                   const nsString& aMessageName) {
+    CrashReporter::AnnotateCrashReport(
+        CrashReporter::Annotation::JSActorName, aActorName);
+    CrashReporter::AnnotateCrashReport(
+        CrashReporter::Annotation::JSActorMessage,
+        NS_LossyConvertUTF16toASCII(aMessageName));
+  }
+  AutoAnnotateMessageInCaseOfCrash(const nsCString& aActorName,
+                                   const nsCString& aMessageName) {
+    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::JSActorName,
+                                       aActorName);
+    CrashReporter::AnnotateCrashReport(
+        CrashReporter::Annotation::JSActorMessage, aMessageName);
+  }
+  ~AutoAnnotateMessageInCaseOfCrash() {
+    CrashReporter::RemoveCrashReportAnnotation(CrashReporter::Annotation::JSActorMessage);
+    CrashReporter::RemoveCrashReportAnnotation(CrashReporter::Annotation::JSActorName);
+  }
+};
+
 void JSWindowActor::StartDestroy() {
+  AutoAnnotateMessageInCaseOfCrash guard(mCName,
+                                         NS_LITERAL_CSTRING("<WillDestroy>"));
   InvokeCallback(CallbackFunction::WillDestroy);
 }
 
 void JSWindowActor::AfterDestroy() {
+  AutoAnnotateMessageInCaseOfCrash guard(mCName,
+                                         NS_LITERAL_CSTRING("<DidDestroy>"));
   InvokeCallback(CallbackFunction::DidDestroy);
   // Clear out & reject mPendingQueries
   RejectPendingQueries();
 }
 
 void JSWindowActor::InvokeCallback(CallbackFunction callback) {
   MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
 
@@ -144,16 +174,17 @@ bool JSWindowActor::AllowMessage(const J
       1);
 
   return false;
 }
 
 void JSWindowActor::SetName(const nsAString& aName) {
   MOZ_ASSERT(mName.IsEmpty(), "Cannot set name twice!");
   mName = aName;
+  mCName = NS_LossyConvertUTF16toASCII(aName);
 }
 
 static ipc::StructuredCloneData CloneJSStack(JSContext* aCx,
                                              JS::Handle<JSObject*> aStack) {
   JS::Rooted<JS::Value> stackVal(aCx, JS::ObjectOrNullValue(aStack));
 
   {
     IgnoredErrorResult rv;
@@ -239,16 +270,17 @@ already_AddRefed<Promise> JSWindowActor:
       MOZ_DIAGNOSTIC_ASSERT(test, msg);    \
     }                                      \
   } while (0)
 
 void JSWindowActor::ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
                                       ipc::StructuredCloneData&& aData,
                                       ipc::StructuredCloneData&& aStack) {
   MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
+  AutoAnnotateMessageInCaseOfCrash guard(mCName, aMetadata.messageName());
 
   AutoEntryScript aes(GetParentObject(), "JSWindowActor message handler");
   JSContext* cx = aes.cx();
 
   // Read the message into a JS object from IPC.
   ErrorResult error;
   JS::Rooted<JS::Value> data(cx);
   aData.Read(cx, &data, error);
--- a/dom/ipc/JSWindowActor.h
+++ b/dom/ipc/JSWindowActor.h
@@ -125,16 +125,19 @@ class JSWindowActor : public nsISupports
 
     RefPtr<JSWindowActor> mActor;
     RefPtr<Promise> mPromise;
     nsString mMessageName;
     uint64_t mQueryId;
   };
 
   nsCOMPtr<nsISupports> mWrappedJS;
+  // A ASCII-encoded version of the name, cached to avoid converting UTF-16 =>
+  // UTF-8 at every message.
+  nsCString mCName;
   nsString mName;
   nsRefPtrHashtable<nsUint64HashKey, Promise> mPendingQueries;
   uint64_t mNextQueryId;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
--- a/toolkit/crashreporter/CrashAnnotations.yaml
+++ b/toolkit/crashreporter/CrashAnnotations.yaml
@@ -548,16 +548,28 @@ IsWaylandDRM:
   type: boolean
 
 JavaStackTrace:
   description: >
     Java stack trace, only present on Firefox for Android if we encounter an
     uncaught Java exception.
   type: string
 
+JSActorMessage:
+  description: >
+    If an actor is currently treating a message, this is the name of the message.
+    Otherwise, empty.
+  type: string
+
+JSActorName:
+  description: >
+    If an actor is currently treating a message, this is the name of the actor.
+    Otherwise, empty.
+  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: >