Assertion failure: !val.isMagic(), at js/src/jsobj.cpp:3637 with Debugger

RESOLVED FIXED in Firefox 36

Status

()

--
critical
RESOLVED FIXED
4 years ago
3 years ago

People

(Reporter: decoder, Assigned: shu)

Tracking

(Blocks: 1 bug, {assertion, regression, testcase})

Trunk
mozilla37
x86_64
Linux
assertion, regression, testcase
Points:
---
Dependency tree / graph
Bug Flags:
in-testsuite +

Firefox Tracking Flags

(firefox36 fixed, firefox37 fixed)

Details

(Whiteboard: [jsbugmon:])

Attachments

(1 attachment, 1 obsolete attachment)

(Reporter)

Description

4 years ago
The following testcase crashes on mozilla-central revision d7c76fe69e9a (build with --enable-optimize --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --enable-debug, run with --no-threads --fuzzing-safe):

var evalInFrame = (function (global) {
  var dbgGlobal = newGlobal();
  var dbg = new dbgGlobal.Debugger();
  return function evalInFrame(upCount, code) {
    dbg.addDebuggee(global);
    var frame = dbg.getNewestFrame().older;
      frame = frame.older;
    var completion = frame.eval(code);
  };
})(this);
function i(save) {
    evalInFrame(1, "a.push(z)", save);
}
function f(b) {
    var a = arguments;
    i.apply(null, a);
}
f(true);



Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00000000009abcd9 in js::ToObjectSlow (cx=0x1a07150, val=..., reportScanStack=true) at js/src/jsobj.cpp:3637
3637	    MOZ_ASSERT(!val.isMagic());
#0  0x00000000009abcd9 in js::ToObjectSlow (cx=0x1a07150, val=..., reportScanStack=true) at js/src/jsobj.cpp:3637
#1  0x0000000000a68e71 in ToObjectFromStack (vp=$jsmagic(JS_OPTIMIZED_ARGUMENTS), cx=0x1a07150) at js/src/jsobj.h:1178
#2  GetPropertyOperation (vp=$jsmagic(JS_OPTIMIZED_ARGUMENTS), lval=$jsmagic(JS_OPTIMIZED_ARGUMENTS), pc=<optimized out>, script=..., fp=0x7fffffff9830, cx=0x1a07150) at js/src/vm/Interpreter.cpp:246
#3  Interpret (cx=0x1a07150, state=...) at js/src/vm/Interpreter.cpp:2359
#4  0x0000000000a6ced7 in js::RunScript (cx=0x1a07150, state=...) at js/src/vm/Interpreter.cpp:434
#5  0x0000000000a6d282 in js::ExecuteKernel (cx=0x1a07150, script=..., scopeChainArg=(JSObject &) @0x7ffff7e5e140 [object Proxy], thisv=..., type=<optimized out>, evalInFrame=..., result=0x7fffffffa3a0) at js/src/vm/Interpreter.cpp:643
#6  0x0000000000a6d894 in js::EvaluateInEnv (cx=0x1a07150, env=(JSObject * const) 0x7ffff7e5e140 [object Proxy], thisv=$jsval((JSObject *) 0x7ffff7e5d060 [object global] delegate), frame=..., chars=..., filename=<optimized out>, lineno=<optimized out>, rval=JSVAL_VOID) at js/src/vm/Debugger.cpp:5639
#7  0x0000000000a81f12 in DebuggerGenericEval (cx=0x1a07150, fullMethodName=<optimized out>, code=..., evalWithBindings=EvalWithDefaultBindings, bindings=..., options=JSVAL_VOID, vp=$jsval((JSObject *) 0x7ffff7e83880 [object Function "eval"]), dbg=0x1af78c0, scope=0x0, iter=0x7fffffffa628) at js/src/vm/Debugger.cpp:5776
#8  0x0000000000a82a56 in DebuggerFrame_eval (cx=0x1a07150, argc=<optimized out>, vp=<optimized out>) at js/src/vm/Debugger.cpp:5790
#9  0x0000000000a8c4a5 in js::CallJSNative (cx=0x1a07150, native=0xa827a0 <DebuggerFrame_eval(JSContext*, unsigned int, JS::Value*)>, args=...) at js/src/jscntxtinlines.h:231
#10 0x0000000000a6db47 in js::Invoke (cx=0x1a07150, args=..., construct=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:484
#11 0x0000000000a6ef9d in js::Invoke (cx=0x1a07150, thisv=..., fval=..., argc=<optimized out>, argv=0x1a80690, rval=$jsval((JSObject *) 0x7ffff7e83880 [object Function "eval"])) at js/src/vm/Interpreter.cpp:540
#12 0x00000000009ec12e in js::DirectProxyHandler::call (this=<optimized out>, cx=0x1a07150, proxy=(JSObject * const) 0x7ffff7e5e120 [object Proxy], args=...) at js/src/proxy/DirectProxyHandler.cpp:75
#13 0x00000000009ec2a5 in js::CrossCompartmentWrapper::call (this=0x19bc540, cx=0x1a07150, wrapper=(JSObject * const) 0x7ffff7e5e120 [object Proxy], args=...) at js/src/proxy/CrossCompartmentWrapper.cpp:296
#14 0x00000000009ea57f in js::Proxy::call (cx=0x1a07150, proxy=(JSObject * const) 0x7ffff7e5e120 [object Proxy], args=...) at js/src/proxy/Proxy.cpp:430
#15 0x00000000009ea66a in js::proxy_Call (cx=0x1a07150, argc=<optimized out>, vp=<optimized out>) at js/src/proxy/Proxy.cpp:812
#16 0x0000000000a8c4a5 in js::CallJSNative (cx=0x1a07150, native=0x9ea600 <js::proxy_Call(JSContext*, unsigned int, JS::Value*)>, args=...) at js/src/jscntxtinlines.h:231
#17 0x0000000000a6ddec in js::Invoke (cx=0x1a07150, args=..., construct=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:477
#18 0x0000000000a5fbf9 in Interpret (cx=0x1a07150, state=...) at js/src/vm/Interpreter.cpp:2541
#19 0x0000000000a6ced7 in js::RunScript (cx=0x1a07150, state=...) at js/src/vm/Interpreter.cpp:434
#20 0x0000000000a6dca5 in js::Invoke (cx=0x1a07150, args=..., construct=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:503
#21 0x0000000000933324 in js_fun_apply (cx=0x1a07150, argc=<optimized out>, vp=0x1a80540) at js/src/jsfun.cpp:1319
#22 0x0000000000a8c4a5 in js::CallJSNative (cx=0x1a07150, native=0x932f90 <js_fun_apply(JSContext*, unsigned int, JS::Value*)>, args=...) at js/src/jscntxtinlines.h:231
#23 0x0000000000a6db47 in js::Invoke (cx=0x1a07150, args=..., construct=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:484
#24 0x0000000000a5fbf9 in Interpret (cx=0x1a07150, state=...) at js/src/vm/Interpreter.cpp:2541
#25 0x0000000000a6ced7 in js::RunScript (cx=0x1a07150, state=...) at js/src/vm/Interpreter.cpp:434
#26 0x0000000000a6d282 in js::ExecuteKernel (cx=0x1a07150, script=..., scopeChainArg=(JSObject &) @0x7ffff7e5d060 [object global] delegate, thisv=..., type=<optimized out>, evalInFrame=..., result=0x0) at js/src/vm/Interpreter.cpp:643
#27 0x0000000000a6d5eb in js::Execute (cx=0x1a07150, script=0x7ffff7e611a8, scopeChainArg=..., rval=0x0) at js/src/vm/Interpreter.cpp:680
#28 0x00000000008dd1bc in ExecuteScript (cx=0x1a07150, obj=(JSObject * const) 0x7ffff7e5d060 [object global] delegate, scriptArg=0x7ffff7e611a8, rval=0x0) at js/src/jsapi.cpp:4708
#29 0x0000000000417aa8 in RunFile (compileOnly=false, file=0x1aef460, filename=0x7fffffffef66 "min.js", obj=..., cx=0x1a07150) at js/src/shell/js.cpp:450
#30 Process (cx=0x1a07150, obj_=<optimized out>, filename=<optimized out>, forceTTY=<optimized out>) at js/src/shell/js.cpp:583
#31 0x0000000000424c29 in ProcessArgs (op=0x7fffffffe960, obj_=<optimized out>, cx=0x1a07150) at js/src/shell/js.cpp:5434
#32 Shell (op=0x7fffffffe960, cx=0x1a07150, envp=<optimized out>) at js/src/shell/js.cpp:5673
#33 main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at js/src/shell/js.cpp:6020
rax	0x0	0
rbx	0x1a07150	27291984
rcx	0x7ffff6cb7910	140737333917968
rdx	0x0	0
rsi	0x7ffff6f8baa0	140737336883872
rdi	0x7ffff6f8a180	140737336877440
rbp	0x7fffffff9310	140737488327440
rsp	0x7fffffff92f0	140737488327408
r8	0x7ffff7fe8740	140737354041152
r9	0x72746e65632d616c	8247338199356891500
r10	0x7fffffff9080	140737488326784
r11	0x7ffff6c3fc90	140737333427344
r12	0x1a80730	27789104
r13	0xfffa000000000009	-1688849860263927
r14	0x1	1
r15	0x1a07168	27292008
rip	0x9abcd9 <js::ToObjectSlow(JSContext*, JS::HandleValue, bool)+313>
=> 0x9abcd9 <js::ToObjectSlow(JSContext*, JS::HandleValue, bool)+313>:	movl   $0x7b,0x0
   0x9abce4 <js::ToObjectSlow(JSContext*, JS::HandleValue, bool)+324>:	callq  0x4049f0 <abort@plt>
(Assignee)

Comment 1

4 years ago
Created attachment 8534758 [details] [diff] [review]
Recover missing arguments when it gets assigned to another slot.

Explanation of bug in comments in the patch.
Attachment #8534758 - Flags: review?(luke)

Comment 2

4 years ago
Comment on attachment 8534758 [details] [diff] [review]
Recover missing arguments when it gets assigned to another slot.

Review of attachment 8534758 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/vm/ScopeObject.cpp
@@ +1513,5 @@
> +    static bool isMagicMissingArgumentsValue(JSContext *cx, ScopeObject &scope, HandleValue v)
> +    {
> +        return v.isMagic() && v.whyMagic() == JS_OPTIMIZED_ARGUMENTS &&
> +               isFunctionScope(scope) &&
> +               !scope.as<CallObject>().callee().nonLazyScript()->needsArgsObj();

Why are the last two conjuncts necessary?  Is it even possible for there to be a JS_OPTIMIZED_ARGUMENTS magic value when needsArgsObj() is true?  I expect there is some terrible case where we only realize we need an args obj at runtime.  But, in that case, don't we still have a problem (we have a magic value).  Assuming it's *not* possible to have this case, then it'd be good to assert the latter two conjuncts instead.

@@ +1570,5 @@
> +        if (!createMissingArguments(cx, scope, &argsObj))
> +            return false;
> +
> +        if (!argsObj) {
> +            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEBUG_NOT_LIVE,

If createMissingArguments fails, it will have already reported an error, so this would be a double-report.  (Same comment for getMissingArguments.)
(Reporter)

Updated

4 years ago
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:bisect]
(Reporter)

Comment 3

4 years ago
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
(Reporter)

Updated

4 years ago
Whiteboard: [jsbugmon:bisect] → [jsbugmon:]
(Assignee)

Comment 4

4 years ago
(In reply to Luke Wagner [:luke] from comment #2)
> Comment on attachment 8534758 [details] [diff] [review]
> Recover missing arguments when it gets assigned to another slot.
> 
> Review of attachment 8534758 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: js/src/vm/ScopeObject.cpp
> @@ +1513,5 @@
> > +    static bool isMagicMissingArgumentsValue(JSContext *cx, ScopeObject &scope, HandleValue v)
> > +    {
> > +        return v.isMagic() && v.whyMagic() == JS_OPTIMIZED_ARGUMENTS &&
> > +               isFunctionScope(scope) &&
> > +               !scope.as<CallObject>().callee().nonLazyScript()->needsArgsObj();
> 
> Why are the last two conjuncts necessary?  Is it even possible for there to
> be a JS_OPTIMIZED_ARGUMENTS magic value when needsArgsObj() is true?  I
> expect there is some terrible case where we only realize we need an args obj
> at runtime.  But, in that case, don't we still have a problem (we have a
> magic value).  Assuming it's *not* possible to have this case, then it'd be
> good to assert the latter two conjuncts instead.
> 

Good point, I'll assert the latter 2 conjuncts.

> @@ +1570,5 @@
> > +        if (!createMissingArguments(cx, scope, &argsObj))
> > +            return false;
> > +
> > +        if (!argsObj) {
> > +            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEBUG_NOT_LIVE,
> 
> If createMissingArguments fails, it will have already reported an error, so
> this would be a double-report.  (Same comment for getMissingArguments.)

There isn't a double reporting AIUI. The second JS_ReportErrorNumber is for when createMissingArguments returned *true* but didn't set the argsObj pointer, since there is no live scope corresponding to it. All cases where createMissingArguments return false, the caller also returns false immediately.

Comment 5

4 years ago
Comment on attachment 8534758 [details] [diff] [review]
Recover missing arguments when it gets assigned to another slot.

(In reply to Shu-yu Guo [:shu] from comment #4)
> There isn't a double reporting AIUI. The second JS_ReportErrorNumber is for
> when createMissingArguments returned *true* but didn't set the argsObj pointer

Hah, you're right.  r+ with the assertion.
Attachment #8534758 - Flags: review?(luke) → review+
https://hg.mozilla.org/mozilla-central/rev/fe70a6c9a374
Status: NEW → RESOLVED
Last Resolved: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla37
(Assignee)

Updated

4 years ago
Blocks: 1114757
Fixed for Fx36 by the roll-up in bug 1114757.
Assignee: nobody → shu
status-firefox36: --- → fixed
status-firefox37: affected → fixed
Flags: in-testsuite?
Flags: in-testsuite? → in-testsuite+
(Assignee)

Comment 8

4 years ago
Created attachment 8584901 [details] [diff] [review]
Relax assertion in DebugScopeProxy::isMagicMissingArgumentsValue.

Oops, the assertion was too strict. Ion can emit OPTIMIZED_ARGUMENTS even when
the script !needsArgsObj(), such as in IonBuilder.cpp:877.
Attachment #8584901 - Flags: review?(nicolas.b.pierron)
(Assignee)

Comment 9

4 years ago
Comment on attachment 8584901 [details] [diff] [review]
Relax assertion in DebugScopeProxy::isMagicMissingArgumentsValue.

Oops, attached to the wrong bug.
Attachment #8584901 - Attachment is obsolete: true
Attachment #8584901 - Flags: review?(nicolas.b.pierron)
Depends on: 1254185
You need to log in before you can comment on or make changes to this bug.