Bug 1380252 - Send only the crashing thread's stack in crash pings; r?ted.mielczarek draft
authorGabriele Svelto <gsvelto@mozilla.com>
Wed, 16 Aug 2017 18:20:40 +0200
changeset 647736 adcb119575c8217350a8a1c72b447ca48958e2ba
parent 647460 6ebc251bd288c268b020815025b05854ccde5c08
child 726632 0f4fb3eff9ce87db4570d903d105d77975871817
push id74538
push usergsvelto@mozilla.com
push dateWed, 16 Aug 2017 22:39:24 +0000
reviewersted.mielczarek
bugs1380252
milestone57.0a1
Bug 1380252 - Send only the crashing thread's stack in crash pings; r?ted.mielczarek This modifies the minidump analyzer to only output the crashing thread's stack when invoked. This reduces the raw size of the crash ping by 50% to 70% depending on the program state when the crash occurred. The minidump-analyzer can still produce the complete output when invoked with the '--full' option. MozReview-Commit-ID: 8KaITWqfBKR
toolkit/crashreporter/minidump-analyzer/minidump-analyzer.cpp
--- a/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.cpp
+++ b/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
 
 #include <cstdio>
+#include <cstring>
 #include <fstream>
 #include <string>
 #include <sstream>
 
 #include "json/json.h"
 #include "google_breakpad/processor/basic_source_line_resolver.h"
 #include "google_breakpad/processor/call_stack.h"
 #include "google_breakpad/processor/code_module.h"
@@ -26,16 +27,23 @@
 #elif defined(XP_UNIX) || defined(XP_MACOSX)
 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
 #endif
 
+// Path of the minidump to be analyzed.
+static string gMinidumpPath;
+
+// When set to true print out the full minidump analysis, otherwise only
+// include the crashing thread in the output.
+static bool gFullMinidump = false;
+
 namespace CrashReporter {
 
 using std::ios;
 using std::ios_base;
 using std::hex;
 using std::ofstream;
 using std::map;
 using std::showbase;
@@ -268,17 +276,20 @@ ConvertProcessStateToJSON(const ProcessS
   Json::Value crashInfo;
   int requestingThread = aProcessState.requesting_thread();
 
   if (aProcessState.crashed()) {
     crashInfo["type"] = aProcessState.crash_reason();
     crashInfo["address"] = ToHex(aProcessState.crash_address());
 
     if (requestingThread != -1) {
-      crashInfo["crashing_thread"] = requestingThread;
+      // Record the crashing thread index only if this is a full minidump
+      // and all threads' stacks are present, otherwise only the crashing
+      // thread stack is written out and this field is set to 0.
+      crashInfo["crashing_thread"] = gFullMinidump ? requestingThread : 0;
     }
   } else {
     crashInfo["type"] = Json::Value(Json::nullValue);
     // Add assertion info, if available
     string assertion = aProcessState.assertion();
 
     if (!assertion.empty()) {
       crashInfo["assertion"] = assertion;
@@ -296,24 +307,35 @@ ConvertProcessStateToJSON(const ProcessS
   }
 
   aRoot["modules"] = modules;
 
   // Threads
   Json::Value threads(Json::arrayValue);
   int threadCount = aProcessState.threads()->size();
 
-  for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex) {
+  if (!gFullMinidump && (requestingThread != -1)) {
+    // Only add the crashing thread
     Json::Value thread;
     Json::Value stack(Json::arrayValue);
-    const CallStack* rawStack = aProcessState.threads()->at(threadIndex);
+    const CallStack* rawStack = aProcessState.threads()->at(requestingThread);
 
     ConvertStackToJSON(aProcessState, orderedModules, rawStack, stack);
     thread["frames"] = stack;
     threads.append(thread);
+   } else {
+    for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex) {
+      Json::Value thread;
+      Json::Value stack(Json::arrayValue);
+      const CallStack* rawStack = aProcessState.threads()->at(threadIndex);
+
+      ConvertStackToJSON(aProcessState, orderedModules, rawStack, stack);
+      thread["frames"] = stack;
+      threads.append(thread);
+    }
   }
 
   aRoot["threads"] = threads;
 }
 
 // Process the minidump file and append the JSON-formatted stack traces to
 // the node specified in |aRoot|
 
@@ -405,33 +427,42 @@ UpdateExtraDataFile(const string &aDumpP
 
   delete f;
 }
 
 } // namespace CrashReporter
 
 using namespace CrashReporter;
 
-int main(int argc, char** argv)
-{
-  string dumpPath;
-
-  if (argc > 1) {
-    dumpPath = argv[1];
-  }
-
-  if (dumpPath.empty()) {
+static void
+ParseArguments(int argc, char** argv) {
+  if (argc <= 1) {
     exit(EXIT_FAILURE);
   }
 
-  if (!FileExists(dumpPath)) {
+  for (int i = 1; i < argc - 1; i++) {
+    if (strcmp(argv[i], "--full") == 0) {
+      gFullMinidump = true;
+    } else {
+      exit(EXIT_FAILURE);
+    }
+  }
+
+  gMinidumpPath = argv[argc - 1];
+}
+
+int main(int argc, char** argv)
+{
+  ParseArguments(argc, argv);
+
+  if (!FileExists(gMinidumpPath)) {
     // The dump file does not exist
-    return 1;
+    exit(EXIT_FAILURE);
   }
 
   // Try processing the minidump
   Json::Value root;
-  if (ProcessMinidump(root, dumpPath)) {
-    UpdateExtraDataFile(dumpPath, root);
+  if (ProcessMinidump(root, gMinidumpPath)) {
+    UpdateExtraDataFile(gMinidumpPath, root);
   }
 
   exit(EXIT_SUCCESS);
 }