Bug 1183355 - Annotate crash reports triggered by MOZ_CRASH in release builds, r=froydnj
authorMichael Layzell <michael@thelayzells.com>
Tue, 29 Sep 2015 11:14:50 -0400
changeset 300251 cb177e743d72a2dc6cb8acf441fca24a6431d4ab
parent 300250 7893f2b7fd2513a0229b40579d0ee8c4a042c37e
child 300252 0e9f34142a508d2b8266c34a314ef71e21a2cded
push id5392
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:08:23 +0000
treeherdermozilla-beta@16ce8562a975 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1183355
milestone44.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 1183355 - Annotate crash reports triggered by MOZ_CRASH in release builds, r=froydnj
mfbt/Assertions.h
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.h
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -16,16 +16,30 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/Compiler.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MacroArgs.h"
 #ifdef MOZ_DUMP_ASSERTION_STACK
 #include "nsTraceRefcnt.h"
 #endif
 
+#if defined(MOZ_CRASHREPORTER) && defined(MOZILLA_INTERNAL_API) && \
+    !defined(MOZILLA_EXTERNAL_LINKAGE) && defined(__cplusplus)
+#  define MOZ_CRASH_CRASHREPORT
+namespace CrashReporter {
+// This declaration is present here as well as in nsExceptionHandler.h
+// nsExceptionHandler.h is not directly included in this file as it includes
+// windows.h, which can cause problems when it is imported into some files due
+// to the number of macros defined.
+// XXX If you change this definition - also change the definition in
+// nsExceptionHandler.h
+void AnnotateMozCrashReason(const char* aReason);
+} // namespace CrashReporter
+#endif
+
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef WIN32
    /*
     * TerminateProcess and GetCurrentProcess are defined in <winbase.h>, which
     * further depends on <windef.h>.  We hardcode these few definitions manually
     * because those headers clutter the global namespace with a significant
@@ -244,17 +258,25 @@ MOZ_ReportCrash(const char* aStr, const 
  *
  * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an
  * explanation-string, we print the string to stderr.  Otherwise, we don't
  * print anything; this is because we want MOZ_CRASH to be 100% safe in release
  * builds, and it's hard to print to stderr safely when memory might have been
  * corrupted.
  */
 #ifndef DEBUG
-#  define MOZ_CRASH(...) MOZ_REALLY_CRASH()
+#  ifdef MOZ_CRASH_CRASHREPORT
+#    define MOZ_CRASH(...) \
+       do { \
+         CrashReporter::AnnotateMozCrashReason("MOZ_CRASH(" __VA_ARGS__ ")"); \
+         MOZ_REALLY_CRASH(); \
+       } while (0)
+#  else
+#    define MOZ_CRASH(...) MOZ_REALLY_CRASH()
+#  endif
 #else
 #  define MOZ_CRASH(...) \
      do { \
        MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \
        MOZ_REALLY_CRASH(); \
      } while (0)
 #endif
 
@@ -504,10 +526,11 @@ struct AssertionConditionType
   do { \
     if ( ( expr ) ) {                       \
       /* Silence MOZ_WARN_UNUSED_RESULT. */ \
     } \
   } while (0)
 #endif
 
 #undef MOZ_DUMP_ASSERTION_STACK
+#undef MOZ_CRASH_CRASHREPORT
 
 #endif /* mozilla_Assertions_h */
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -180,16 +180,17 @@ static char const * const kCrashEventAnn
   // "IsGarbageCollecting"
   // "AvailablePageFile"
   // "AvailableVirtualMemory"
   // "SystemMemoryUsePercentage"
   // "OOMAllocationSize"
   // "TotalPageFile"
   // "TotalPhysicalMemory"
   // "TotalVirtualMemory"
+  // "MozCrashReason"
 };
 
 static const char kCrashMainID[] = "crash.main.2\n";
 
 static google_breakpad::ExceptionHandler* gExceptionHandler = nullptr;
 
 static XP_CHAR* pendingDirectory;
 static XP_CHAR* crashReporterPath;
@@ -448,16 +449,23 @@ Concat(XP_CHAR* str, const XP_CHAR* toAp
   memcpy(str, toAppend, appendLen * sizeof(XP_CHAR));
   str += appendLen;
   *str = '\0';
   *size -= appendLen;
 
   return str;
 }
 
+static const char* gMozCrashReason = nullptr;
+
+void AnnotateMozCrashReason(const char* aReason)
+{
+  gMozCrashReason = aReason;
+}
+
 static size_t gOOMAllocationSize = 0;
 
 void AnnotateOOMAllocationSize(size_t size)
 {
   gOOMAllocationSize = size;
 }
 
 #ifndef XP_WIN
@@ -836,16 +844,22 @@ bool MinidumpCallback(
       WRITE_STATEX_FIELD(ullTotalPageFile, "TotalPageFile", _ui64toa);
       WRITE_STATEX_FIELD(ullAvailPageFile, "AvailablePageFile", _ui64toa);
       WRITE_STATEX_FIELD(ullTotalPhys, "TotalPhysicalMemory", _ui64toa);
       WRITE_STATEX_FIELD(ullAvailPhys, "AvailablePhysicalMemory", _ui64toa);
 
 #undef WRITE_STATEX_FIELD
     }
 #endif // XP_WIN
+
+    if (gMozCrashReason) {
+      WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason);
+      WriteAnnotation(eventFile, "MozCrashReason", gMozCrashReason);
+    }
+
     if (oomAllocationSizeBuffer[0]) {
       WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer);
       WriteAnnotation(eventFile, "OOMAllocationSize", oomAllocationSizeBuffer);
     }
 
     if (memoryReportPath) {
       WriteLiteral(apiData, "ContainsMemoryReport=1\n");
       WriteLiteral(eventFile, "ContainsMemoryReport=1\n");
--- a/toolkit/crashreporter/nsExceptionHandler.h
+++ b/toolkit/crashreporter/nsExceptionHandler.h
@@ -66,16 +66,19 @@ nsresult SetMinidumpPath(const nsAString
 
 // AnnotateCrashReport, RemoveCrashReportAnnotation and
 // AppendAppNotesToCrashReport may be called from any thread in a chrome
 // process, but may only be called from the main thread in a content process.
 nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data);
 nsresult RemoveCrashReportAnnotation(const nsACString& key);
 nsresult AppendAppNotesToCrashReport(const nsACString& data);
 
+// NOTE: If you change this definition, also change the definition in Assertions.h
+// as it is intended to be defining this same function.
+void AnnotateMozCrashReason(const char* aReason);
 void AnnotateOOMAllocationSize(size_t size);
 nsresult SetGarbageCollecting(bool collecting);
 void SetEventloopNestingLevel(uint32_t level);
 
 nsresult SetRestartArgs(int argc, char** argv);
 nsresult SetupExtraData(nsIFile* aAppDataDirectory,
                         const nsACString& aBuildID);
 bool GetLastRunCrashID(nsAString& id);