Closed Bug 1645358 Opened 4 years ago Closed 2 years ago

Crash [@ js::ErrorObject::create] or Assertion failure: stack->canUnwrapAs<SavedFrame>(), at vm/SavedStacks-inl.h:25 with Debugger

Categories

(Core :: JavaScript Engine, defect, P3)

x86_64
Linux
defect

Tracking

()

VERIFIED FIXED
108 Branch
Tracking Status
firefox-esr102 --- wontfix
firefox79 --- wontfix
firefox106 --- wontfix
firefox107 --- wontfix
firefox108 --- verified

People

(Reporter: decoder, Assigned: jandem)

References

(Blocks 1 open bug)

Details

(4 keywords, Whiteboard: [bugmon:update,bisected,confirmed])

Crash Data

Attachments

(2 files)

The following testcase crashes on mozilla-central revision 20200612-fea1e502ea28 (opt build, run with --fuzzing-safe --cpu-count=2 --ion-offthread-compile=off):

nukeAllCCWs();
var dbg = new Debugger;
dbg.onNewGlobalObject = function(global) {
    var gw = dbg.addDebuggee(global);
    gw.defineProperty(gw.length, {
        value: -1
    });
};
newGlobal({
    newCompartment: true
});

Backtrace:

received signal SIGSEGV, Segmentation fault.
#0  0x00005555558bbf27 in js::ErrorObject::create(JSContext*, JSExnType, JS::Handle<JSObject*>, JS::Handle<JSString*>, unsigned int, unsigned int, unsigned int, mozilla::UniquePtr<JSErrorReport, JS::DeletePolicy<JSErrorReport> >, JS::Handle<JSString*>, JS::Handle<JSObject*>) ()
#1  0x0000555555837721 in js::CopyErrorObject(JSContext*, JS::Handle<js::ErrorObject*>) ()
#2  0x000055555586d18f in js::ErrorCopier::~ErrorCopier() ()
#3  0x0000555555b95086 in js::DebuggerObject::defineProperty(JSContext*, JS::Handle<js::DebuggerObject*>, JS::Handle<JS::PropertyKey>, JS::Handle<JS::PropertyDescriptor>) ()
#4  0x0000555555b94d6c in js::DebuggerObject::CallData::definePropertyMethod() ()
#5  0x0000555555ba13aa in bool js::DebuggerObject::CallData::ToNative<&js::DebuggerObject::CallData::definePropertyMethod>(JSContext*, unsigned int, JS::Value*) ()
#6  0x00005555557a105b in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) ()
#7  0x000055555579a626 in Interpret(JSContext*, js::RunState&) ()
#8  0x0000555555791b44 in js::RunScript(JSContext*, js::RunState&) ()
#9  0x00005555557a15b9 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) ()
#10 0x00005555557a1ace in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) ()
#11 0x0000555555b42436 in js::Debugger::fireNewGlobalObject(JSContext*, JS::Handle<js::GlobalObject*>) ()
#12 0x0000555555b4296b in js::DebugAPI::slowPathOnNewGlobalObject(JSContext*, JS::Handle<js::GlobalObject*>) ()
#13 0x000055555582236c in JS_FireOnNewGlobalObject(JSContext*, JS::Handle<JSObject*>) ()
#14 0x0000555555697501 in NewGlobalObject(JSContext*, JS::RealmOptions&, JSPrincipals*, ShellGlobalKind) ()
#15 0x00005555556a1fa5 in NewGlobal(JSContext*, unsigned int, JS::Value*) ()
#16 0x00005555557a105b in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) ()
[...]
#24 0x000055555568b269 in main ()
rax	0x5555565d0c5f	93825009519711
rbx	0x555557647910	93825026783504
rcx	0x5555576c98f0	93825027315952
rdx	0x7fffffffaf58	140737488334680
rsi	0x7	7
rdi	0x34d78d68e080	58100395073664
rbp	0x7fffffffaf10	140737488334608
rsp	0x7fffffffae90	140737488334480
r8	0x2	2
r9	0x5	5
r10	0x5555565c1958	93825009457496
r11	0x7fffffffaf40	140737488334656
r12	0x7	7
r13	0x7fffffffaf58	140737488334680
r14	0x7ffff6023000	140737320726528
r15	0x2	2
rip	0x5555558bbf27 <js::ErrorObject::create(JSContext*, JSExnType, JS::Handle<JSObject*>, JS::Handle<JSString*>, unsigned int, unsigned int, unsigned int, mozilla::UniquePtr<JSErrorReport, JS::DeletePolicy<JSErrorReport> >, JS::Handle<JSString*>, JS::Handle<JSObject*>)+711>
=> 0x5555558bbf27 <_ZN2js11ErrorObject6createEP9JSContext9JSExnTypeN2JS6HandleIP8JSObjectEENS5_IP8JSStringEEjjjN7mozilla9UniquePtrI13JSErrorReportNS4_12DeletePolicyISE_EEEESB_S8_+711>:	movl   $0x19,0x0
   0x5555558bbf32 <_ZN2js11ErrorObject6createEP9JSContext9JSExnTypeN2JS6HandleIP8JSObjectEENS5_IP8JSStringEEjjjN7mozilla9UniquePtrI13JSErrorReportNS4_12DeletePolicyISE_EEEESB_S8_+722>:	callq  0x5555556d0e00 <abort>
Attached file Testcase
Whiteboard: [bugmon:update,bisect] → [bugmon:update,bisected,confirmed]
Bugmon Analysis:
Verified bug as reproducible on mozilla-central 20200612145655-9388507a8b1f.
Failed to bisect testcase (Start build crashes!):
> Start: 7445a65187306dfa0fc18492e7b198887a146b18 (20190614033939)
> End: fea1e502ea281a9b86b821957e622f0b0d081ce7 (20200612094620)
> BuildFlags: BuildFlags(asan=False, tsan=False, debug=True, fuzzing=False, coverage=False, valgrind=False)

This might just be a bad assert.

We're erroring within a defineProperty on the global (the "undefined" property), and the error-copier tries to unwrap the underlying stack frame object and save it. The unwrap of the SavedFrame fails, however.. because the underlying compartment has been nuked, and a DeadProxyObject is returned in its place.

The offending behaviour occurs here:

https://searchfox.org/mozilla-central/rev/cfaa250d14e344834932de4c2eed0061701654da/js/src/jsexn.cpp#704

That call to wrap produces a DeadProxyObject instead of a real one. Later on, the error-copying code tries to unwrap any proxies and get back at the underlying SavedFrame*. Unwrapping a DeadProxyObject back into a SavedFrame doesn't work, and we end up at the crash site here:

https://searchfox.org/mozilla-central/rev/cfaa250d14e344834932de4c2eed0061701654da/js/src/vm/SavedStacks-inl.h#25

Personally, I don't really have an understanding of why things are being wrapped and then later unwrapped in the same code. That said, this doesn't feel very serious. I don't know why the underlying compartment is getting nuked, but it seems like a weird corner case situation.

Jason, I thought you would be able to reason a bit better about what's happening in detail.

Flags: needinfo?(jorendorff)

AFAIK wrap() can always produce a DeadProxyObject. That assertion is therefore invalid. Code that relies on that being true, like this:

https://searchfox.org/mozilla-central/rev/5a4aaccb28665807a6fd49cf48367d47fbb5a19a/js/src/builtin/Promise.cpp#3905-3906

must be changed to cope with the CCW/DeadProxyObject case.

A comment on ErrorObject::stack(), pointing out the CopyErrorObject special case, would be welcome too.

Because only the Debugger copies errors, this is not a very severe bug.

Flags: needinfo?(jorendorff)
Severity: -- → S3
Flags: needinfo?(kvijayan)

Clear a needinfo that is pending on an inactive user.

Inactive users most likely will not respond; if the missing information is essential and cannot be collected another way, the bug maybe should be closed as INCOMPLETE.

For more information, please visit auto_nag documentation.

Flags: needinfo?(kvijayan)

I had an old JS shell lying around and managed to reproduce this failure.

Jan, is this bug reproducible on a recent build and based on comment 4, could this be related to Realms?

Blocks: sm-runtime
Severity: S3 → S4
Flags: needinfo?(jdemooij)
Priority: -- → P3
Assignee: nobody → jdemooij
Status: NEW → ASSIGNED
Flags: needinfo?(jdemooij)
Pushed by jdemooij@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/a39f6a18c02d
Handle DeadObjectProxy in js::CopyErrorObject. r=evilpie
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 108 Branch

Bugmon Analysis
Verified bug as fixed on rev mozilla-central 20221019211615-a1297d435b3f.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.

Status: RESOLVED → VERIFIED
Keywords: bugmon
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: