Closed Bug 1412659 Opened 7 years ago Closed 7 years ago

Crash [@ CheckCanChangeActiveContext] with GC and evalInCooperativeThread

Categories

(Core :: JavaScript Engine, defect, P1)

x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
mozilla58
Tracking Status
firefox-esr52 --- unaffected
firefox56 --- wontfix
firefox57 --- wontfix
firefox58 --- fixed

People

(Reporter: decoder, Assigned: bhackett1024)

Details

(4 keywords, Whiteboard: [jsbugmon:update])

Crash Data

Attachments

(1 file)

The following testcase crashes on mozilla-central revision c16bc8097c10 (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --enable-stdcxx-compat --disable-profiling --disable-debug --enable-optimize, run with --fuzzing-safe --baseline-eager --ion-offthread-compile=off):

try {
  evaluate(`
  function f() {
    var o = { g: function () { return "with-g"; } };
    with (o) {
      eval(\`{
        function g() { return gc(); }
      }\`);
    }
    f(g);
  }
  f();
`);
} catch (exc) {}
evalInCooperativeThread(`
try { 
  function f() {
    var o = { g: function () { return "with-g"; } };
    with (o) {
      eval(\`{
        function g() { return gc(); }
      }\`);
    }
    f(g + "");
  }
  f();
} catch(exc) {}
`);


Backtrace:

received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff1bff700 (LWP 28054)]
CheckCanChangeActiveContext (rt=rt@entry=0x7ffff6946000) at js/src/vm/Runtime.cpp:361
#0  CheckCanChangeActiveContext (rt=rt@entry=0x7ffff6946000) at js/src/vm/Runtime.cpp:361
#1  0x00000000009c82b1 in JSRuntime::setActiveContext (this=0x7ffff6946000, cx=cx@entry=0x0) at js/src/vm/Runtime.cpp:372
#2  0x00000000007fee5e in js::YieldCooperativeContext (cx=cx@entry=0x7ffff1c2f000) at js/src/jscntxt.cpp:204
#3  JS_YieldCooperativeContext (cx=cx@entry=0x7ffff1c2f000) at js/src/jsapi.cpp:496
#4  0x0000000000451192 in CooperativeBeginWait (cx=0x7ffff1c2f000) at js/src/shell/js.cpp:3368
#5  CooperativeYieldCallback (cx=0x7ffff1c2f000) at js/src/shell/js.cpp:3432
#6  0x0000000000b7c429 in JSContext::yieldToEmbedding (this=0x7ffff1c2f000) at js/src/jscntxt.h:307
#7  js::ZoneGroup::enter (this=0x7ffff69161c0, cx=cx@entry=0x7ffff1c2f000) at js/src/gc/ZoneGroup.cpp:71
#8  0x0000000000b61a16 in JSContext::enterZoneGroup (group=<optimized out>, this=0x7ffff1c2f000) at js/src/jscntxtinlines.h:543
#9  JSContext::enterNonAtomsCompartment (c=0x7ffff6935800, this=0x7ffff1c2f000) at js/src/jscntxtinlines.h:459
#10 JSContext::enterCompartmentOf<js::ObjectGroup*> (target=<synthetic pointer>, this=0x7ffff1c2f000) at js/src/jscntxtinlines.h:483
#11 js::AutoCompartment::AutoCompartment<js::ObjectGroup*> (target=<synthetic pointer>, cx=0x7ffff1c2f000, this=<synthetic pointer>) at js/src/jscompartmentinlines.h:52
#12 js::Nursery::collect (this=this@entry=0x7ffff6948650, reason=reason@entry=JS::gcreason::FULL_CELL_PTR_BUFFER) at js/src/gc/Nursery.cpp:661
#13 0x0000000000842940 in js::gc::GCRuntime::minorGC (this=this@entry=0x7ffff69464d0, reason=reason@entry=JS::gcreason::FULL_CELL_PTR_BUFFER, phase=phase@entry=js::gcstats::PhaseKind::MINOR_GC) at js/src/jsgc.cpp:7687
#14 0x000000000086823f in js::gc::GCRuntime::minorGC (phase=js::gcstats::PhaseKind::MINOR_GC, reason=<optimized out>, this=0x7ffff69464d0) at js/src/jsgc.cpp:7754
#15 js::gc::GCRuntime::gcIfRequested (this=this@entry=0x7ffff69464d0) at js/src/jsgc.cpp:7734
#16 0x0000000000ad6242 in js::gc::GCRuntime::gcIfNeededAtAllocation (cx=0x7ffff1c2f000, this=0x7ffff69464d0) at js/src/gc/Allocator.cpp:237
#17 js::gc::GCRuntime::checkAllocatorState<(js::AllowGC)1> (this=0x7ffff69464d0, cx=0x7ffff1c2f000, kind=<optimized out>) at js/src/gc/Allocator.cpp:192
#18 0x0000000000ad6be3 in js::Allocate<JSScript, (js::AllowGC)1> (cx=cx@entry=0x7ffff1c2f000) at js/src/gc/Allocator.cpp:143
#19 0x00000000008977e6 in JSScript::Create (cx=cx@entry=0x7ffff1c2f000, options=..., sourceObject=..., sourceObject@entry=..., bufStart=20, bufEnd=39, toStringStart=10, toStringEnd=39) at js/src/jsscript.cpp:2708
#20 0x0000000000906bd7 in js::frontend::CompileLazyFunction (cx=cx@entry=0x7ffff1c2f000, lazy=lazy@entry=..., chars=0x7ffff6971b28 u"() { return gc(); }\n      }", length=length@entry=19) at js/src/frontend/BytecodeCompiler.cpp:697
#21 0x0000000000855432 in JSFunction::createScriptForLazilyInterpretedFunction (cx=0x7ffff1c2f000, fun=fun@entry=...) at js/src/jsfun.cpp:1632
#22 0x00000000008707e9 in JSFunction::getOrCreateScript (cx=<optimized out>, fun=...) at js/src/jsfun.h:451
#23 0x0000000000855b70 in js::FunctionToString (cx=0x7ffff1c2f000, fun=..., fun@entry=..., isToSource=<optimized out>) at js/src/jsfun.cpp:1008
#24 0x00000000008560e1 in fun_toStringHelper (cx=<optimized out>, obj=..., isToSource=<optimized out>) at js/src/jsfun.cpp:1148
#25 0x00000000008561a0 in js::fun_toString (cx=0x7ffff1c2f000, argc=<optimized out>, vp=0x7ffff1b8f620) at js/src/jsfun.cpp:1175
#26 0x0000000000524f24 in js::CallJSNative (args=..., native=0x856130 <js::fun_toString(JSContext*, unsigned int, JS::Value*)>, cx=0x7ffff1c2f000) at js/src/jscntxtinlines.h:291
#27 js::InternalCallOrConstruct (cx=cx@entry=0x7ffff1c2f000, args=..., construct=construct@entry=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:472
#28 0x0000000000525345 in InternalCall (cx=cx@entry=0x7ffff1c2f000, args=...) at js/src/vm/Interpreter.cpp:521
#29 0x00000000005253a8 in js::Call (cx=cx@entry=0x7ffff1c2f000, fval=..., fval@entry=..., thisv=..., thisv@entry=..., args=..., rval=..., rval@entry=...) at js/src/vm/Interpreter.cpp:540
#30 0x000000000087641e in js::Call (rval=..., thisObj=<optimized out>, fval=..., cx=0x7ffff1c2f000) at js/src/vm/Interpreter.h:94
#31 MaybeCallMethod (cx=cx@entry=0x7ffff1c2f000, obj=obj@entry=..., id=..., id@entry=..., vp=vp@entry=...) at js/src/jsobj.cpp:3048
#32 0x000000000087d49f in JS::OrdinaryToPrimitive (cx=cx@entry=0x7ffff1c2f000, obj=obj@entry=..., hint=hint@entry=JSTYPE_UNDEFINED, vp=vp@entry=...) at js/src/jsobj.cpp:3131
#33 0x000000000087dab1 in js::ToPrimitiveSlow (cx=0x7ffff1c2f000, preferredType=preferredType@entry=JSTYPE_UNDEFINED, vp=..., vp@entry=...) at js/src/jsobj.cpp:3178
#34 0x00000000007213ec in js::ToPrimitive (vp=..., cx=0x7ffff1c2f000) at js/src/jsobj.h:997
#35 js::jit::ConvertObjectToStringForConcat (cx=0x7ffff1c2f000, obj=..., obj@entry=...) at js/src/jit/SharedIC.cpp:976
#36 0x0000000000721478 in js::jit::DoConcatStringObject (cx=0x7ffff1c2f000, lhsIsString=<optimized out>, lhs=..., rhs=..., res=...) at js/src/jit/SharedIC.cpp:999
#37 0x00001818f609a14c in ?? ()
[...]
#46 0x0000000000000000 in ?? ()
rax	0x1b6cb40	28756800
rbx	0xe35328	14897960
rcx	0x0	0
rdx	0x0	0
rsi	0x7ffff1c2f000	140737249472512
rdi	0x0	0
rbp	0x0	0
rsp	0x7ffff1b8e510	140737248814352
r8	0x0	0
r9	0x0	0
r10	0x1	1
r11	0x246	582
r12	0x7ffff1c2f000	140737249472512
r13	0x7ffff1c2f000	140737249472512
r14	0x7ffff1b8e5f0	140737248814576
r15	0x7ffff6948650	140737330316880
rip	0x9c63e7 <CheckCanChangeActiveContext(JSRuntime*)+279>
=> 0x9c63e7 <CheckCanChangeActiveContext(JSRuntime*)+279>:	movl   $0x0,0x0
   0x9c63f2 <CheckCanChangeActiveContext(JSRuntime*)+290>:	ud2


Marking this s-s to be safe, because the test uses GC. Also, this only reproduces in optimized builds, not in debug.
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:update]
JSBugMon: Bisection requested, result:
autoBisect shows this is probably related to the following changeset:

The first bad revision is:
changeset:   https://hg.mozilla.org/mozilla-central/rev/eb6525931ba0
user:        Brian Hackett
date:        Wed Apr 12 13:10:46 2017 -1000
summary:     Bug 1347539 - Keep track of the Ion lazy link list at the zone group level, r=h4writer.

This iteration took 221.674 seconds to run.
Flags: needinfo?(bhackett1024)
Attached patch patchSplinter Review
In general during GC the active cooperating thread can collect things from whichever zone groups it wants, but it can't actually enter compartments without having exclusive access to the compartment's zone group.  In this case we are trying to mark an object group as needing pre-tenuring, which requires the current thread to be in the object group's zone group.  That object group could be from any zone group, though.  This patch only marks object groups as needing pre-tenuring if the current thread can acquire ownership of its zone group without yielding (which is not allowed during GC).

This is not s-s but I don't seem to be able to remove that flag from the bug.
Assignee: nobody → bhackett1024
Flags: needinfo?(bhackett1024)
Attachment #8923355 - Flags: review?(jcoppeard)
Group: javascript-core-security
Attachment #8923355 - Flags: review?(jcoppeard) → review+
Pushed by bhackett@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/fb45a6a34063
Only mark object groups as needing pretenuring if the current thread can access their zone group, r=jonco.
Priority: -- → P1
https://hg.mozilla.org/mozilla-central/rev/fb45a6a34063
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla58
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: