Bug 984361 - Crash earlier in DIAGNOSTICS mode if we mark a nullptr; r=sfink

This commit is contained in:
Terrence Cole 2014-05-09 14:20:04 -07:00
parent ff54855fd2
commit 69227604e3
3 changed files with 43 additions and 7 deletions

View File

@ -8,6 +8,8 @@
#include "mozilla/DebugOnly.h"
#include "jsprf.h"
#include "jit/IonCode.h"
#include "js/SliceBudget.h"
#include "vm/ArgumentsObject.h"
@ -146,12 +148,27 @@ template <> bool ThingIsPermanentAtom<PropertyName>(PropertyName *name) { return
template<typename T>
static inline void
CheckMarkedThing(JSTracer *trc, T *thing)
CheckMarkedThing(JSTracer *trc, T **thingp)
{
#ifdef DEBUG
JS_ASSERT(trc);
JS_ASSERT(thing);
JS_ASSERT(thingp);
T *thing = *thingp;
#ifdef JS_CRASH_DIAGNOSTICS
if (!thing) {
char msgbuf[1024];
const char *label = trc->tracingName("<unknown>");
JS_snprintf(msgbuf, sizeof(msgbuf),
"[crash diagnostics] Marking nullptr \"%s\" @ %p of type %s",
label, thingp, TraceKindAsAscii(MapTypeToTraceKind<T>::kind));
MOZ_ReportAssertionFailure(msgbuf, __FILE__, __LINE__);
MOZ_CRASH();
}
#endif
JS_ASSERT(*thingp);
#ifdef DEBUG
/* This function uses data that's not available in the nursery. */
if (IsInsideNursery(trc->runtime(), thing))
return;
@ -199,17 +216,16 @@ CheckMarkedThing(JSTracer *trc, T *thing)
JS_ASSERT_IF(IsThingPoisoned(thing) && rt->isHeapBusy(),
!InFreeList(thing->arenaHeader(), thing));
#endif
}
template<typename T>
static void
MarkInternal(JSTracer *trc, T **thingp)
{
JS_ASSERT(thingp);
CheckMarkedThing(trc, thingp);
T *thing = *thingp;
CheckMarkedThing(trc, thing);
if (!trc->callback) {
/*
* We may mark a Nursery thing outside the context of the
@ -276,7 +292,7 @@ MarkPermanentAtom(JSTracer *trc, JSAtom *atom, const char *name)
JS_ASSERT(atom->isPermanent());
CheckMarkedThing(trc, atom);
CheckMarkedThing(trc, &atom);
if (!trc->callback) {
// Atoms do not refer to other GC things so don't need to go on the mark stack.

View File

@ -305,6 +305,22 @@ const uint32_t Arena::FirstThingOffsets[] = {
#undef OFFSET
const char *
TraceKindAsAscii(JSGCTraceKind kind)
{
switch(kind) {
case JSTRACE_OBJECT: return "JSTRACE_OBJECT";
case JSTRACE_STRING: return "JSTRACE_STRING";
case JSTRACE_SCRIPT: return "JSTRACE_SCRIPT";
case JSTRACE_LAZY_SCRIPT: return "JSTRACE_SCRIPT";
case JSTRACE_JITCODE: return "JSTRACE_JITCODE";
case JSTRACE_SHAPE: return "JSTRACE_SHAPE";
case JSTRACE_BASE_SHAPE: return "JSTRACE_BASE_SHAPE";
case JSTRACE_TYPE_OBJECT: return "JSTRACE_TYPE_OBJECT";
default: return "INVALID";
}
}
/*
* Finalization order for incrementally swept things.
*/

View File

@ -161,6 +161,10 @@ template <> struct MapTypeToTraceKind<JSLinearString> { static const JSGCTrace
template <> struct MapTypeToTraceKind<PropertyName> { static const JSGCTraceKind kind = JSTRACE_STRING; };
template <> struct MapTypeToTraceKind<jit::JitCode> { static const JSGCTraceKind kind = JSTRACE_JITCODE; };
/* Return a printable string for the given kind, for diagnostic purposes. */
const char *
TraceKindAsAscii(JSGCTraceKind kind);
/* Map from C++ type to finalize kind. JSObject does not have a 1:1 mapping, so must use Arena::thingSize. */
template <typename T> struct MapTypeToFinalizeKind {};
template <> struct MapTypeToFinalizeKind<JSScript> { static const AllocKind kind = FINALIZE_SCRIPT; };