Bug 1324093 - Part 1: Move MOZ_REALLY_CRASH's null-deref and TerminateProcess into a never-inline function. r=froydnj
authorDavid Major <dmajor@mozilla.com>
Wed, 18 Jan 2017 09:33:25 +1300
changeset 376998 9939303eecf11c1cdba510c7f3f180fb1d4faafd
parent 376997 9bd54089097bfc41ab6c728ef63736b9168c51ae
child 376999 58b1e40375e6f48f23f5d6422f9c6e0e15bb3eb7
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1324093
milestone53.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 1324093 - Part 1: Move MOZ_REALLY_CRASH's null-deref and TerminateProcess into a never-inline function. r=froydnj The C versus C++ distinction was only there so that Android could make sure it used the global ::abort. I didn't see the need to maintain the distinction for Windows. (Besides, with this change we're no longer doing textual inclusion of "TerminateProcess" in the macro, so people can't take over the name.) Linux's abort sequence wasn't long enough to be troublesome, so I left it alone. MozReview-Commit-ID: Ah5XtWpevGz
mfbt/Assertions.h
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -42,17 +42,17 @@ AnnotateMozCrashReason(const char* reaso
 #  define MOZ_CRASH_ANNOTATE(...) AnnotateMozCrashReason(__VA_ARGS__)
 #else
 #  define MOZ_CRASH_ANNOTATE(...) do { /* nothing */ } while (0)
 #endif
 
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef WIN32
+#ifdef _MSC_VER
    /*
     * 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
     * number of undesired macros and symbols.
     */
 MOZ_BEGIN_EXTERN_C
 __declspec(dllimport) int __stdcall
@@ -187,52 +187,43 @@ MOZ_ReportCrash(const char* aStr, const 
  */
 #if defined(_MSC_VER)
    /*
     * On MSVC use the __debugbreak compiler intrinsic, which produces an inline
     * (not nested in a system function) breakpoint.  This distinctively invokes
     * Breakpad without requiring system library symbols on all stack-processing
     * machines, as a nested breakpoint would require.
     *
+    * We use __LINE__ to prevent the compiler from folding multiple crash sites
+    * together, which would make crash reports hard to understand.
+    *
     * We use TerminateProcess with the exit code aborting would generate
     * because we don't want to invoke atexit handlers, destructors, library
     * unload handlers, and so on when our process might be in a compromised
     * state.
     *
     * We don't use abort() because it'd cause Windows to annoyingly pop up the
     * process error dialog multiple times.  See bug 345118 and bug 426163.
     *
-    * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the
-    * compiler doesn't hassle us to provide a return statement after a
-    * MOZ_REALLY_CRASH() call.
-    *
     * (Technically these are Windows requirements, not MSVC requirements.  But
     * practically you need MSVC for debugging, and we only ship builds created
     * by MSVC, so doing it this way reduces complexity.)
     */
 
-__declspec(noreturn) __inline void MOZ_NoReturn() {}
+static MOZ_COLD MOZ_NORETURN MOZ_NEVER_INLINE void MOZ_NoReturn(int aLine)
+{
+  *((volatile int*) NULL) = aLine;
+  TerminateProcess(GetCurrentProcess(), 3);
+}
 
-#  ifdef __cplusplus
-#    define MOZ_REALLY_CRASH() \
-       do { \
-         ::__debugbreak(); \
-         *((volatile int*) NULL) = __LINE__; \
-         ::TerminateProcess(::GetCurrentProcess(), 3); \
-         ::MOZ_NoReturn(); \
-       } while (0)
-#  else
-#    define MOZ_REALLY_CRASH() \
-       do { \
-         __debugbreak(); \
-         *((volatile int*) NULL) = __LINE__; \
-         TerminateProcess(GetCurrentProcess(), 3); \
-         MOZ_NoReturn(); \
-       } while (0)
-#  endif
+#  define MOZ_REALLY_CRASH() \
+     do { \
+       __debugbreak(); \
+       MOZ_NoReturn(__LINE__); \
+     } while (0)
 #else
 #  ifdef __cplusplus
 #    define MOZ_REALLY_CRASH() \
        do { \
          *((volatile int*) NULL) = __LINE__; \
          ::abort(); \
        } while (0)
 #  else