Bug 753283 - Poison VM stack to help fuzzing (r=bhackett)

This commit is contained in:
Bill McCloskey 2012-05-16 14:10:58 -07:00
parent 7ab2fc7430
commit dc73485a13
6 changed files with 60 additions and 2 deletions

View File

@ -0,0 +1,27 @@
var summary = '';
function printStatus (msg) {
var lines = msg.split ("\n");
}
evaluate("\
function f() {\
var ss = [\
new f(Int8Array, propertyIsEnumerable, '[let (x = 3, y = 4) x].map(0)')\
];\
}\
try {\
f();\
} catch (e) {}\
gczeal(4);\
printStatus (summary);\
");
evaluate("\
function g(n, h) {\
var a = f;\
if (n <= 0) \
return f; \
var t = g(n - 1, h);\
var r = function(x) { };\
}\
g(80, f);\
");

View File

@ -697,6 +697,14 @@ ObjectValue(JSObject &obj)
return v;
}
static JS_ALWAYS_INLINE Value
ObjectValueCrashOnTouch()
{
Value v;
v.setObject(*reinterpret_cast<JSObject *>(0x42));
return v;
}
static JS_ALWAYS_INLINE Value
MagicValue(JSWhyMagic why)
{

View File

@ -1356,11 +1356,11 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
# define DO_OP() JS_BEGIN_MACRO \
CHECK_PCCOUNT_INTERRUPTS(); \
js::gc::MaybeVerifyBarriers(cx); \
JS_EXTENSION_(goto *jumpTable[op]); \
JS_END_MACRO
# define DO_NEXT_OP(n) JS_BEGIN_MACRO \
TypeCheckNextBytecode(cx, script, n, regs); \
js::gc::MaybeVerifyBarriers(cx); \
op = (JSOp) *(regs.pc += (n)); \
DO_OP(); \
JS_END_MACRO

View File

@ -351,7 +351,7 @@ Debug_SetValueRangeToCrashOnTouch(Value *beg, Value *end)
{
#ifdef DEBUG
for (Value *v = beg; v != end; ++v)
v->setObject(*reinterpret_cast<JSObject *>(0x42));
*v = ObjectValueCrashOnTouch();
#endif
}

View File

@ -1231,6 +1231,10 @@ mjit::Compiler::markUndefinedLocal(uint32_t offset, uint32_t i)
Lifetime *lifetime = analysis->liveness(slot).live(offset);
if (lifetime)
masm.storeValue(UndefinedValue(), local);
#ifdef DEBUG
else
masm.storeValue(ObjectValueCrashOnTouch(), local);
#endif
}
}
@ -1243,6 +1247,14 @@ mjit::Compiler::markUndefinedLocals()
*/
for (uint32_t i = 0; i < script->nfixed; i++)
markUndefinedLocal(0, i);
#ifdef DEBUG
uint32_t depth = ssa.getFrame(a->inlineIndex).depth;
for (uint32_t i = script->nfixed; i < script->nslots; i++) {
Address local(JSFrameReg, sizeof(StackFrame) + (depth + i) * sizeof(Value));
masm.storeValue(ObjectValueCrashOnTouch(), local);
}
#endif
}
CompileStatus

View File

@ -414,6 +414,7 @@ StackSpace::init()
trustedEnd_ = base_ + CAPACITY_VALS;
conservativeEnd_ = defaultEnd_ = trustedEnd_ - BUFFER_VALS;
#endif
Debug_SetValueRangeToCrashOnTouch(base_, trustedEnd_);
assertInvariants();
return true;
}
@ -759,9 +760,14 @@ ContextStack::popInvokeArgs(const InvokeArgsGuard &iag)
JS_ASSERT(onTop());
JS_ASSERT(space().firstUnused() == seg_->calls().end());
Value *oldend = seg_->end();
seg_->popCall();
if (iag.pushedSeg_)
popSegment();
if (seg_)
Debug_SetValueRangeToCrashOnTouch(seg_->end(), oldend);
}
bool
@ -872,10 +878,15 @@ ContextStack::popFrame(const FrameGuard &fg)
if (fg.regs_.fp()->isNonEvalFunctionFrame())
fg.regs_.fp()->functionEpilogue();
Value *oldend = seg_->end();
seg_->popRegs(fg.prevRegs_);
if (fg.pushedSeg_)
popSegment();
if (seg_)
Debug_SetValueRangeToCrashOnTouch(seg_->end(), oldend);
/*
* NB: this code can call out and observe the stack (e.g., through GC), so
* it should only be called from a consistent stack state.