Bug 587982 - Log MS CRT Warnings and Abort on MS CRT Errors and Assertions, r=ted.mielczarek.
authorBob Clary <bclary@bclary.com>
Mon, 27 Aug 2012 12:12:32 -0700
changeset 105629 ceb5b26840e0855b4cd4e6596243741f7cbb26b8
parent 105628 807627473028c796f805d27c9601647ef99a48bb
child 105630 c3333e6e37aa746ccf694a9faa8091d5112988ab
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersted
bugs587982
milestone17.0a1
Bug 587982 - Log MS CRT Warnings and Abort on MS CRT Errors and Assertions, r=ted.mielczarek.
toolkit/xre/nsAppRunner.cpp
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1341,21 +1341,56 @@ DumpHelp()
 #endif
 
   // this works, but only after the components have registered.  so if you drop in a new command line handler, -help
   // won't not until the second run.
   // out of the bug, because we ship a component.reg file, it works correctly.
   DumpArbitraryHelp();
 }
 
+#if defined(DEBUG) && defined(XP_WIN)
 #ifdef DEBUG_warren
-#ifdef XP_WIN
 #define _CRTDBG_MAP_ALLOC
+#endif
+// Set a CRT ReportHook function to capture and format MSCRT
+// warnings, errors and assertions.
+// See http://msdn.microsoft.com/en-US/library/74kabxyx(v=VS.80).aspx
+#include <stdio.h>
 #include <crtdbg.h>
-#endif
+#include "mozilla/mozalloc_abort.h"
+static int MSCRTReportHook( int aReportType, char *aMessage, int *oReturnValue)
+{
+  *oReturnValue = 0; // continue execution
+
+  // Do not use fprintf or other functions which may allocate
+  // memory from the heap which may be corrupted. Instead,
+  // use fputs to output the leading portion of the message
+  // and use mozalloc_abort to emit the remainder of the
+  // message.
+
+  switch(aReportType) {
+  case 0:
+    fputs("\nWARNING: CRT WARNING", stderr);
+    fputs(aMessage, stderr);
+    fputs("\n", stderr);
+    break;
+  case 1:
+    fputs("\n###!!! ABORT: CRT ERROR ", stderr);
+    mozalloc_abort(aMessage);
+    break;
+  case 2:
+    fputs("\n###!!! ABORT: CRT ASSERT ", stderr);
+    mozalloc_abort(aMessage);
+    break;
+  }
+
+  // do not invoke the debugger
+  return 1;
+}
+
 #endif
 
 #if defined(FREEBSD)
 // pick up fpsetmask prototype.
 #include <ieeefp.h>
 #endif
 
 static inline void
@@ -4075,16 +4110,31 @@ SetupErrorHandling(const char* progname)
   // for a dozen of the dialog boxes to litter the console
   if (getenv("XRE_NO_WINDOWS_CRASH_DIALOG"))
     realMode |= SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
 
   SetErrorMode(realMode);
 
 #endif
 
+#if defined (DEBUG) && defined(XP_WIN)
+  // Send MSCRT Warnings, Errors and Assertions to stderr.
+  // See http://msdn.microsoft.com/en-us/library/1y71x448(v=VS.80).aspx
+  // and http://msdn.microsoft.com/en-us/library/a68f826y(v=VS.80).aspx.
+
+  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
+  _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
+  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
+  _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+
+  _CrtSetReportHook(MSCRTReportHook);
+#endif
+
 #ifndef XP_OS2
   InstallSignalHandlers(progname);
 #endif
 
   // Unbuffer stdout, needed for tinderbox tests.
   setbuf(stdout, 0);
 
 #if defined(FREEBSD)