Closed Bug 1238422 Opened 9 years ago Closed 9 years ago

Crash [@ js::jit::AutoWritableJitCode::~AutoWritableJitCode] or [@ js::jit::AutoWritableJitCode::AutoWritableJitCode]


(Core :: JavaScript Engine, defect)

Not set





(Reporter: gkw, Unassigned)



(5 keywords, Whiteboard: [jsbugmon:ignore])

Crash Data

The following testcase crashes on mozilla-central revision c33f30666b37 (build with --32 --enable-more-deterministic, run with --fuzzing-safe --no-threads --ion-eager):

function testMathyFunction(f, inputs) {
    var results = [];
    for (var j = 0; j < 199; ++j) {
        for (var k = 0; k < 199; ++k) {
            try {
                results.push(f(inputs[j], inputs[k]));
            } catch (e) {}
mathy2 = function(x, y) {
    return (y > Math.hypot ? x : Math.round(x, y | y > x))
valueOf = function() {
    "use asm"
    function f() {}
    return f
mathy1 = function(x, y)(y + y, x % y / y == Math.max(y, x))
mathy3 = function(x, y) {
    mathy2(mathy2(), y, mathy1(x, x)) + y
    y ^ y
    x == mathy2(Math.round(x) + mathy2(x, y))
    Math.min(x, y)
testMathyFunction(mathy3, [eval, this, this, eval, eval, eval,
                           eval, eval, eval, this, this, this,
                           this, eval, eval, this, eval, this, eval


#0  js::jit::AutoWritableJitCode::~AutoWritableJitCode (this=<optimized out>, __in_chrg=<optimized out>) at js/src/jit/JitCompartment.h:566
#1  InvalidateActivation (fop=fop@entry=0xffe7abac, activations=..., invalidateAll=invalidateAll@entry=true) at js/src/jit/Ion.cpp:3012
#2  0x081d1eb2 in js::jit::InvalidateAll (fop=0xffe7abac, zone=0xf7150800) at js/src/jit/Ion.cpp:3054
#3  0x0860a35f in JS::Zone::discardJitCode (this=0xf7150800, fop=0xffe7abac) at js/src/gc/Zone.cpp:235
#4  0x083d48ee in js::gc::GCRuntime::beginSweepingZoneGroup (this=0xf712520c) at js/src/jsgc.cpp:5187
#5  0x083d7769 in js::gc::GCRuntime::beginSweepPhase (this=0xf712520c, destroyingRuntime=false) at js/src/jsgc.cpp:5346
#6  0x083dcb92 in js::gc::GCRuntime::incrementalCollectSlice (this=0xf712520c, budget=..., reason=JS::gcreason::LAST_DITCH) at js/src/jsgc.cpp:6107
#7  0x083dd8d4 in js::gc::GCRuntime::gcCycle (this=0xf712520c, nonincrementalByAPI=true, budget=..., reason=JS::gcreason::LAST_DITCH) at js/src/jsgc.cpp:6315
#8  0x083ddd7e in js::gc::GCRuntime::collect (this=0xf712520c, nonincrementalByAPI=true, budget=..., reason=JS::gcreason::LAST_DITCH) at js/src/jsgc.cpp:6421
#9  0x083de1be in js::gc::GCRuntime::gc (this=0xf712520c, gckind=GC_SHRINK, reason=JS::gcreason::LAST_DITCH) at js/src/jsgc.cpp:6479
#10 0x085e88b1 in js::gc::GCRuntime::tryNewTenuredThing<JSObject, (js::AllowGC)1> (cx=0xf7172040, kind=js::gc::AllocKind::STRING, thingSize=16) at js/src/gc/Allocator.cpp:256
#11 0x085e8ec7 in js::Allocate<JSString, (js::AllowGC)1> (cx=0xf7172040) at js/src/gc/Allocator.cpp:215
#12 0x0853c586 in JSFlatString::new_<(js::AllowGC)1, unsigned char> (length=38, chars=0xe191c0d0 "function hypot() {\n    [native code]\n}", cx=0xf7172040) at js/src/vm/String-inl.h:223
#13 js::NewStringDontDeflate<(js::AllowGC)1, unsigned char> (cx=0xf7172040, chars=0xe191c0d0 "function hypot() {\n    [native code]\n}", length=38) at js/src/vm/String.cpp:1079
#14 0x08533de9 in FinishStringFlat<unsigned char, mozilla::Vector<unsigned char, 64u, js::TempAllocPolicy> > (cb=..., sb=..., cx=<optimized out>) at js/src/vm/StringBuffer.cpp:87
#15 js::StringBuffer::finishString (this=0xffe7b00c) at js/src/vm/StringBuffer.cpp:128
#16 0x083d324c in js::FunctionToString (cx=0xf7172040, fun=..., lambdaParen=true) at js/src/jsfun.cpp:1105
#17 0x083d37a8 in fun_toStringHelper (cx=0xf7172040, obj=..., indent=0) at js/src/jsfun.cpp:1123
#18 0x083d38af in js::fun_toString (cx=0xf7172040, argc=0, vp=0xffe7b1cc) at js/src/jsfun.cpp:1141
#19 0x084aefd1 in js::CallJSNative (args=..., native=<optimized out>, cx=0xf7172040) at js/src/jscntxtinlines.h:235
#20 js::Invoke (cx=0xf7172040, args=..., construct=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:477
#21 0x084b0661 in js::Invoke (cx=0xf7172040, thisv=..., fval=..., argc=0, argv=0x0, rval=...) at js/src/vm/Interpreter.cpp:529
#22 0x083ee859 in MaybeCallMethod (cx=cx@entry=0xf7172040, obj=obj@entry=..., id=..., id@entry=..., vp=...) at js/src/jsobj.cpp:3004
#23 0x083f1690 in JS::OrdinaryToPrimitive (cx=0xf7172040, obj=..., hint=JSTYPE_NUMBER, vp=...) at js/src/jsobj.cpp:3087
#24 0x083f1b79 in js::ToPrimitiveSlow (cx=0xf7172040, preferredType=JSTYPE_NUMBER, vp=...) at js/src/jsobj.cpp:3134
#25 0x082e940f in js::ToPrimitive (vp=..., preferredType=JSTYPE_NUMBER, cx=0xf7172040) at js/src/jsobj.h:1031
#26 js::GreaterThanOperation (res=0xffe7b41c, rhs=..., lhs=..., cx=0xf7172040) at js/src/vm/Interpreter-inl.h:682
#27 js::jit::GreaterThan (cx=0xf7172040, lhs=..., rhs=..., res=0xffe7b41c) at js/src/jit/VMFunctions.cpp:261
#28 0xf7790023 in ?? ()

Although this seems like a null de-ref, this involves JIT code, so setting s-s. The testcase is intermittent.
Setting needinfo? from Jan as a start.
Flags: needinfo?(jdemooij)
autoBisect shows this is probably related to the following changeset:

The first bad revision is:
user:        Jan de Mooij
date:        Mon Dec 28 21:05:50 2015 +0100
summary:     Bug 1215479 - Turn on W^X JIT code by default. r=luke

Jan, is bug 1215479 a likely regressor?
Blocks: 1215479
(In reply to Gary Kwong [:gkw] [:nth10sd] from comment #0)
> this involves JIT code, so setting s-s. The testcase is intermittent.

And also because there is GC on the stack.
I think this is similar to bug 1236530. Because asm.js pages interleave executable and writable code, the kernel has too many mappings and refuses to add more. That bug made W^X failures fallible for asm.js code.

Handling this gracefully in all other cases is much more complicated so we just crash. Here we're probably creating a ton of asm.js modules and then do some non-asm.js stuff and crash...

This situation is very unlikely to come up in the browser. Luke, could we limit the number of (active) asm.js modules per runtime to something large like 1000 or something? Or trigger a GC in this case?
Flags: needinfo?(jdemooij) → needinfo?(luke)
(In reply to Jan de Mooij [:jandem] from comment #4)
> Because asm.js pages interleave executable and writable code

This may sound confusing, we interleave executable and writable *pages*. The pages that are writable are not for code but for data.
Jan: yeah, perhaps we could clamp to 1,000 (or 5,000 or 10,000 --- I think the limit here is 64k mappings) as some global shared Atomic (to account for multiple workers etc) and, if we hit that limit, call the LargeAllocationFailureCallback (which should do a sync gc/cc/gc) and try again.
Flags: needinfo?(luke)
I'm going to mark this sec-other because it sounds like the browser is just running out of memory in some kind of odd way.
Group: javascript-core-security
Naveed, can you find an assignee?
Flags: needinfo?(nihsanullah)
This is very likely a duplicate of bug 1238694. I'll land the patch for that.
Closed: 9 years ago
Flags: needinfo?(nihsanullah)
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.