Allow finalizing external crash reports from CrashReportHost. (bug 1338281 part 4, r=billm)
authorDavid Anderson <danderson@mozilla.com>
Wed, 15 Feb 2017 14:44:30 -0800
changeset 343208 0e7adc2bbf8e3c9cdb4f4cd8ea24b9126a274840
parent 343207 5d5c80258cb2c6e5d84c70ea832a2fcd708afde3
child 343209 2e78a0da72687a894a87dcb742d8cdd78c85c21c
push id31372
push usercbook@mozilla.com
push dateThu, 16 Feb 2017 12:16:10 +0000
treeherdermozilla-central@2737f66ad6ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1338281
milestone54.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
Allow finalizing external crash reports from CrashReportHost. (bug 1338281 part 4, r=billm)
dom/media/gmp/GMPParent.cpp
ipc/glue/CrashReporterHost.cpp
ipc/glue/CrashReporterHost.h
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -467,18 +467,22 @@ GMPParent::WriteExtraDataForMinidump()
 bool
 GMPParent::GetCrashID(nsString& aResult)
 {
   if (!mCrashReporter) {
     return false;
   }
 
   WriteExtraDataForMinidump();
+  if (!mCrashReporter->GenerateCrashReport(OtherPid())) {
+    return false;
+  }
 
-  return mCrashReporter->GenerateCrashReport(OtherPid(), &aResult);
+  aResult = mCrashReporter->MinidumpID();
+  return true;
 }
 
 static void
 GMPNotifyObservers(const uint32_t aPluginID, const nsACString& aPluginName, const nsAString& aPluginDumpID)
 {
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   nsCOMPtr<nsIWritablePropertyBag2> propbag =
     do_CreateInstance("@mozilla.org/hash-property-bag;1");
--- a/ipc/glue/CrashReporterHost.cpp
+++ b/ipc/glue/CrashReporterHost.cpp
@@ -19,29 +19,40 @@ namespace mozilla {
 namespace ipc {
 
 CrashReporterHost::CrashReporterHost(GeckoProcessType aProcessType,
                                      const Shmem& aShmem,
                                      CrashReporter::ThreadId aThreadId)
  : mProcessType(aProcessType),
    mShmem(aShmem),
    mThreadId(aThreadId),
-   mStartTime(::time(nullptr))
+   mStartTime(::time(nullptr)),
+   mFinalized(false)
 {
 }
 
 #ifdef MOZ_CRASHREPORTER
 bool
-CrashReporterHost::GenerateCrashReport(RefPtr<nsIFile> aCrashDump,
-                                       nsString* aOutMinidumpID)
+CrashReporterHost::GenerateCrashReport(base::ProcessId aPid)
 {
-  nsString dumpID;
-  if (!CrashReporter::GetIDFromMinidump(aCrashDump, dumpID)) {
+  RefPtr<nsIFile> crashDump;
+  if (!XRE_TakeMinidumpForChild(aPid, getter_AddRefs(crashDump), nullptr)) {
+    return false;
+  }
+  if (!CrashReporter::GetIDFromMinidump(crashDump, mDumpID)) {
     return false;
   }
+  return FinalizeCrashReport();
+}
+
+bool
+CrashReporterHost::FinalizeCrashReport()
+{
+  MOZ_ASSERT(!mFinalized);
+  MOZ_ASSERT(HasMinidump());
 
   CrashReporter::AnnotationTable notes;
 
   nsAutoCString type;
   switch (mProcessType) {
     case GeckoProcessType_Content:
       type = NS_LITERAL_CSTRING("content");
       break;
@@ -58,22 +69,22 @@ CrashReporterHost::GenerateCrashReport(R
   }
   notes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
 
   char startTime[32];
   SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime));
   notes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
 
   CrashReporterMetadataShmem::ReadAppNotes(mShmem, &notes);
-  CrashReporter::AppendExtraData(dumpID, mExtraNotes);
-  CrashReporter::AppendExtraData(dumpID, notes);
+  CrashReporter::AppendExtraData(mDumpID, mExtraNotes);
+  CrashReporter::AppendExtraData(mDumpID, notes);
 
-  NotifyCrashService(mProcessType, dumpID, &notes);
+  NotifyCrashService(mProcessType, mDumpID, &notes);
 
-  *aOutMinidumpID = dumpID;
+  mFinalized = true;
   return true;
 }
 
 /**
  * Runnable used to execute the minidump analyzer program asynchronously after
  * a crash. This should run on a background thread not to block the main thread
  * over the potentially long minidump analysis. Once analysis is over, the
  * crash information will be relayed to the crash manager via another runnable
--- a/ipc/glue/CrashReporterHost.h
+++ b/ipc/glue/CrashReporterHost.h
@@ -26,48 +26,57 @@ class CrashReporterHost
   typedef CrashReporter::AnnotationTable AnnotationTable;
 
 public:
   CrashReporterHost(GeckoProcessType aProcessType,
                     const Shmem& aShmem,
                     CrashReporter::ThreadId aThreadId);
 
 #ifdef MOZ_CRASHREPORTER
-  bool GenerateCrashReport(base::ProcessId aPid,
-                           nsString* aOutMinidumpID = nullptr)
-  {
-    RefPtr<nsIFile> crashDump;
-    if (!XRE_TakeMinidumpForChild(aPid, getter_AddRefs(crashDump), nullptr)) {
-      return false;
-    }
-    return GenerateCrashReport(crashDump, aOutMinidumpID);
-  }
+  // Helper function for generating a crash report for a process that probably
+  // crashed (i.e., had an AbnormalShutdown in ActorDestroy). Returns true if
+  // the process has a minidump attached and we were able to generate a report.
+  bool GenerateCrashReport(base::ProcessId aPid);
+
+  // If a minidump was already captured (e.g. via the hang reporter), this
+  // finalizes the existing report by attaching metadata and notifying the
+  // crash service.
+  bool FinalizeCrashReport();
 
   // 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);
 
   void AddNote(const nsCString& aKey, const nsCString& aValue);
+
+  bool HasMinidump() const {
+    return !mDumpID.IsEmpty();
+  }
+  const nsString& MinidumpID() const {
+    MOZ_ASSERT(HasMinidump());
+    return mDumpID;
+  }
 #endif
 
 private:
-  bool GenerateCrashReport(RefPtr<nsIFile> aCrashDump, nsString* aOutMinidumpID);
   static void AsyncAddCrash(int32_t aProcessType, int32_t aCrashType,
                             const nsString& aChildDumpID);
 
 private:
   GeckoProcessType mProcessType;
   Shmem mShmem;
   CrashReporter::ThreadId mThreadId;
   time_t mStartTime;
   AnnotationTable mExtraNotes;
+  nsString mDumpID;
+  bool mFinalized;
 };
 
 } // namespace ipc
 } // namespace mozilla
 
 #endif // mozilla_ipc_CrashReporterHost_h