Bug 1277448 patch 6 - Make MFBT assertion messages print the function name. r?Waldo draft
authorL. David Baron <dbaron@dbaron.org>
Tue, 21 Jun 2016 18:10:53 -0700
changeset 380463 5084f0961bf82057676bef59d5f944cd317f1870
parent 380462 bf62498839e6228e47cd329da05f23763965d963
child 523734 95761f6b5a32964b7389be96a66eb48e5ee4ec11
push id21228
push userdbaron@mozilla.com
push dateWed, 22 Jun 2016 01:11:03 +0000
reviewersWaldo
bugs1277448
milestone50.0a1
Bug 1277448 patch 6 - Make MFBT assertion messages print the function name. r?Waldo MozReview-Commit-ID: A5lg11Cx51T
ipc/glue/BackgroundChildImpl.cpp
js/src/gc/Verifier.cpp
js/src/jit/MacroAssembler.cpp
js/src/jit/mips32/Simulator-mips32.cpp
js/src/jit/mips64/Simulator-mips64.cpp
js/src/jscntxt.cpp
js/src/jsutil.cpp
js/src/shell/js.cpp
js/src/vm/TypeInference.cpp
layout/base/nsPresArena.cpp
mfbt/Assertions.h
mfbt/Attributes.h
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -133,17 +133,18 @@ BackgroundChildImpl::ProcessingError(Res
 #undef HANDLE_CASE
 
     default:
       MOZ_CRASH("Unknown error code!");
   }
 
   // This is just MOZ_CRASH() un-inlined so that we can pass the result code as
   // a string. MOZ_CRASH() only supports string literals at the moment.
-  MOZ_ReportCrash(abortMessage.get(), __FILE__, __LINE__); MOZ_REALLY_CRASH();
+  MOZ_ReportCrash(abortMessage.get(), __FILE__, __func__, __LINE__);
+  MOZ_REALLY_CRASH();
 }
 
 void
 BackgroundChildImpl::ActorDestroy(ActorDestroyReason aWhy)
 {
   // May happen on any thread!
 }
 
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -293,17 +293,17 @@ AssertMarkedOrAllocated(const EdgeValue&
     // Permanent atoms and well-known symbols aren't marked during graph traversal.
     if (edge.kind == JS::TraceKind::String && static_cast<JSString*>(edge.thing)->isPermanentAtom())
         return;
     if (edge.kind == JS::TraceKind::Symbol && static_cast<JS::Symbol*>(edge.thing)->isWellKnownSymbol())
         return;
 
     char msgbuf[1024];
     JS_snprintf(msgbuf, sizeof(msgbuf), "[barrier verifier] Unmarked edge: %s", edge.label);
-    MOZ_ReportAssertionFailure(msgbuf, __FILE__, __LINE__);
+    MOZ_ReportAssertionFailure(msgbuf, __FILE__, __func__, __LINE__);
     MOZ_CRASH();
 }
 
 void
 gc::GCRuntime::endVerifyPreBarriers()
 {
     VerifyPreTracer* trc = verifyPreData;
 
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1463,17 +1463,17 @@ MacroAssembler::handleFailure()
     // running function and never come back
     JitCode* excTail = GetJitContext()->runtime->jitRuntime()->getExceptionTail();
     jump(excTail);
 }
 
 #ifdef DEBUG
 static void
 AssumeUnreachable_(const char* output) {
-    MOZ_ReportAssertionFailure(output, __FILE__, __LINE__);
+    MOZ_ReportAssertionFailure(output, __FILE__, __func__, __LINE__);
 }
 #endif
 
 void
 MacroAssembler::assumeUnreachable(const char* output)
 {
 #ifdef DEBUG
     if (!IsCompilingAsmJS()) {
--- a/js/src/jit/mips32/Simulator-mips32.cpp
+++ b/js/src/jit/mips32/Simulator-mips32.cpp
@@ -1349,17 +1349,17 @@ class Redirection
                 MOZ_ASSERT(current->type() == type);
                 return current;
             }
         }
 
         Redirection* redir = (Redirection*)js_malloc(sizeof(Redirection));
         if (!redir) {
             MOZ_ReportAssertionFailure("[unhandlable oom] Simulator redirection",
-                                       __FILE__, __LINE__);
+                                       __FILE__, __func__, __LINE__);
             MOZ_CRASH();
         }
         new(redir) Redirection(nativeFunction, type, sim);
         return redir;
     }
 
     static Redirection* FromSwiInstruction(SimInstruction* swiInstruction) {
         uint8_t* addrOfSwi = reinterpret_cast<uint8_t*>(swiInstruction);
--- a/js/src/jit/mips64/Simulator-mips64.cpp
+++ b/js/src/jit/mips64/Simulator-mips64.cpp
@@ -1362,17 +1362,17 @@ class Redirection
                 MOZ_ASSERT(current->type() == type);
                 return current;
             }
         }
 
         Redirection* redir = (Redirection*)js_malloc(sizeof(Redirection));
         if (!redir) {
             MOZ_ReportAssertionFailure("[unhandlable oom] Simulator redirection",
-                                       __FILE__, __LINE__);
+                                       __FILE__, __func__, __LINE__);
             MOZ_CRASH();
         }
         new(redir) Redirection(nativeFunction, type, sim);
         return redir;
     }
 
     static Redirection* FromSwiInstruction(SimInstruction* swiInstruction) {
         uint8_t* addrOfSwi = reinterpret_cast<uint8_t*>(swiInstruction);
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1146,17 +1146,17 @@ CompartmentChecker::check(AbstractFrameP
 }
 #endif
 
 void
 AutoEnterOOMUnsafeRegion::crash(const char* reason)
 {
     char msgbuf[1024];
     JS_snprintf(msgbuf, sizeof(msgbuf), "[unhandlable oom] %s", reason);
-    MOZ_ReportAssertionFailure(msgbuf, __FILE__, __LINE__);
+    MOZ_ReportAssertionFailure(msgbuf, __FILE__, __func__, __LINE__);
     MOZ_CRASH();
 }
 
 AutoEnterOOMUnsafeRegion::AnnotateOOMAllocationSizeCallback
 AutoEnterOOMUnsafeRegion::annotateOOMSizeCallback = nullptr;
 
 void
 AutoEnterOOMUnsafeRegion::crash(size_t size, const char* reason)
--- a/js/src/jsutil.cpp
+++ b/js/src/jsutil.cpp
@@ -80,17 +80,17 @@ ResetSimulatedOOM() {
 
 } // namespace oom
 } // namespace js
 #endif // defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
 
 JS_PUBLIC_API(void)
 JS_Assert(const char* s, const char* file, int ln)
 {
-    MOZ_ReportAssertionFailure(s, file, ln);
+    MOZ_ReportAssertionFailure(s, file, "[unknown]", ln);
     MOZ_CRASH();
 }
 
 #ifdef __linux__
 
 #include <malloc.h>
 #include <stdlib.h>
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2747,17 +2747,17 @@ Crash(JSContext* cx, unsigned argc, Valu
     if (args.length() == 0)
         MOZ_CRASH("forced crash");
     RootedString message(cx, JS::ToString(cx, args[0]));
     if (!message)
         return false;
     char* utf8chars = JS_EncodeStringToUTF8(cx, message);
     if (!utf8chars)
         return false;
-    MOZ_ReportCrash(utf8chars, __FILE__, __LINE__);
+    MOZ_ReportCrash(utf8chars, __FILE__, __func__, __LINE__);
     MOZ_CRASH_ANNOTATE("MOZ_CRASH(dynamic)");
     MOZ_REALLY_CRASH();
 }
 
 static bool
 GetSLX(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -297,17 +297,17 @@ js::TypeFailure(JSContext* cx, const cha
     JS_vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
     va_end(ap);
 
     JS_snprintf(msgbuf, sizeof(msgbuf), "[infer failure] %s", errbuf);
 
     /* Dump type state, even if INFERFLAGS is unset. */
     PrintTypes(cx, cx->compartment(), true);
 
-    MOZ_ReportAssertionFailure(msgbuf, __FILE__, __LINE__);
+    MOZ_ReportAssertionFailure(msgbuf, __FILE__, __func__, __LINE__);
     MOZ_CRASH();
 }
 
 /////////////////////////////////////////////////////////////////////
 // TypeSet
 /////////////////////////////////////////////////////////////////////
 
 TemporaryTypeSet::TemporaryTypeSet(LifoAlloc* alloc, Type type)
--- a/layout/base/nsPresArena.cpp
+++ b/layout/base/nsPresArena.cpp
@@ -145,17 +145,17 @@ nsPresArena::Allocate(uint32_t aCode, si
           MOZ_ReportAssertionFailure(
             nsPrintfCString("PresArena: poison overwritten; "
                             "wanted %.16" PRIx64 " "
                             "found %.16" PRIx64 " "
                             "errors in bits %.16" PRIx64 " ",
                             uint64_t(mozPoisonValue()),
                             uint64_t(val),
                             uint64_t(mozPoisonValue() ^ val)).get(),
-            __FILE__, __LINE__);
+            __FILE__, __func__, __LINE__);
           MOZ_CRASH();
         }
       }
     }
 #endif
     MOZ_MAKE_MEM_UNDEFINED(result, list->mEntrySize);
     return result;
   }
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -155,41 +155,46 @@ extern "C" {
  * Prints |aStr| as an assertion failure (using aFilename and aLine as the
  * location of the assertion) to the standard debug-output channel.
  *
  * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method.  This
  * method is primarily for internal use in this header, and only secondarily
  * for use in implementing release-build assertions.
  */
 static MOZ_COLD MOZ_ALWAYS_INLINE void
-MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine)
+MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename,
+                           const char* aFunction, int aLine)
   MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
 {
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert",
-                      "Assertion failure: %s, at %s:%d\n",
-                      aStr, aFilename, aLine);
+                      "Assertion failure: %s, at %s:%d in %s\n",
+                      aStr, aFilename, aLine, aFunction);
 #else
-  fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine);
+  fprintf(stderr, "Assertion failure: %s, at %s:%d in %s\n",
+          aStr, aFilename, aLine, aFunction);
 #if defined (MOZ_DUMP_ASSERTION_STACK)
   nsTraceRefcnt::WalkTheStack(stderr);
 #endif
   fflush(stderr);
 #endif
 }
 
 static MOZ_COLD MOZ_ALWAYS_INLINE void
-MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine)
+MOZ_ReportCrash(const char* aStr, const char* aFilename, const char* aFunction,
+                int aLine)
   MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
 {
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
-                      "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine);
+                      "Hit MOZ_CRASH(%s) at %s:%d in %s\n",
+                      aStr, aFilename, aLine, aFunction);
 #else
-  fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine);
+  fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d in %s\n",
+          aStr, aFilename, aLine, aFunction);
 #if defined(MOZ_DUMP_ASSERTION_STACK)
   nsTraceRefcnt::WalkTheStack(stderr);
 #endif
   fflush(stderr);
 #endif
 }
 
 /**
@@ -280,17 +285,17 @@ MOZ_ReportCrash(const char* aStr, const 
 #  define MOZ_CRASH(...) \
      do { \
        MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ "), file " __FILE__); \
        MOZ_REALLY_CRASH(); \
      } while (0)
 #else
 #  define MOZ_CRASH(...) \
      do { \
-       MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \
+       MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __func__, __LINE__); \
        MOZ_CRASH_ANNOTATE("MOZ_CRASH(" __VA_ARGS__ "), file " __FILE__); \
        MOZ_REALLY_CRASH(); \
      } while (0)
 #endif
 
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
@@ -375,27 +380,28 @@ struct AssertionConditionType
 #  define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x)
 #endif
 
 /* First the single-argument form. */
 #define MOZ_ASSERT_HELPER1(expr) \
   do { \
     MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \
     if (MOZ_UNLIKELY(!(expr))) { \
-      MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \
+      MOZ_ReportAssertionFailure(#expr, __FILE__, __func__, __LINE__); \
       MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr "), file " __FILE__); \
       MOZ_REALLY_CRASH(); \
     } \
   } while (0)
 /* Now the two-argument form. */
 #define MOZ_ASSERT_HELPER2(expr, explain) \
   do { \
     MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \
     if (MOZ_UNLIKELY(!(expr))) { \
-      MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \
+      MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __func__, \
+                                 __LINE__); \
       MOZ_CRASH_ANNOTATE("MOZ_RELEASE_ASSERT(" #expr ") (" explain \
                          "), file " __FILE__); \
       MOZ_REALLY_CRASH(); \
     } \
   } while (0)
 
 #define MOZ_RELEASE_ASSERT_GLUE(a, b) a b
 #define MOZ_RELEASE_ASSERT(...) \
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -223,17 +223,18 @@
 #endif
 
 /*
  * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function
  * declaration, indicates that for the purposes of static analysis, this
  * function does not return.  (The function definition does not need to be
  * annotated.)
  *
- * MOZ_ReportCrash(const char* s, const char* file, int ln)
+ * MOZ_ReportCrash(const char* s, const char* file, const char* function,
+ *                 int ln)
  *   MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
  *
  * Some static analyzers, like scan-build from clang, can use this information
  * to eliminate false positives.  From the upstream documentation of scan-build:
  * "This attribute is useful for annotating assertion handlers that actually
  * can return, but for the purpose of using the analyzer we want to pretend
  * that such functions do not return."
  *