Closed
Bug 609244
Opened 14 years ago
Closed 14 years ago
crash [@ PopActiveVMFrame ]
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
RESOLVED
FIXED
Tracking | Status | |
---|---|---|
blocking2.0 | --- | beta8+ |
People
(Reporter: scoobidiver, Assigned: dmandelin)
Details
(Keywords: crash, regression, topcrash, Whiteboard: fixed-in-tracemonkey)
Crash Data
Attachments
(1 file)
10.78 KB,
patch
|
dvander
:
review+
|
Details | Diff | Splinter Review |
It is a new crash signature. As it is discontinious, the regression range can not be determined. It is #95 top crasher in 4.0b8pre for the last week. Signature PopActiveVMFrame UUID 4045b063-d25d-4364-83e1-420972101102 Time 2010-11-02 22:18:50.623763 Uptime 20663 Last Crash 189886 seconds (2.2 days) before submission Install Age 20663 seconds (5.7 hours) since version was first installed. Product Firefox Version 4.0b8pre Build ID 20101102042148 Branch 2.0 OS Windows NT OS Version 6.1.7600 CPU x86 CPU Info GenuineIntel family 6 model 30 stepping 5 Crash Reason EXCEPTION_ACCESS_VIOLATION_READ Crash Address 0xc App Notes AdapterVendorID: 10de, AdapterDeviceID: 05e2 Frame Module Signature [Expand] Source 0 mozjs.dll PopActiveVMFrame js/src/methodjit/MethodJIT.cpp:126 1 mozjs.dll JaegerThrowpoline js/src/methodjit/MethodJIT.cpp:650 2 mozjs.dll js::mjit::EnterMethodJIT js/src/methodjit/MethodJIT.cpp:739 3 mozjs.dll CheckStackAndEnterMethodJIT js/src/methodjit/MethodJIT.cpp:764 4 mozjs.dll js::mjit::JaegerShot js/src/methodjit/MethodJIT.cpp:781 5 mozjs.dll js::RunScript js/src/jsinterp.cpp:662 6 mozjs.dll js::Invoke js/src/jsinterp.cpp:768 7 mozjs.dll js::ExternalInvoke js/src/jsinterp.cpp:881 8 mozjs.dll JS_CallFunctionValue js/src/jsapi.cpp:4895 9 xul.dll nsJSContext::CallEventHandler dom/base/nsJSEnvironment.cpp:2171 10 xul.dll nsGlobalWindow::RunTimeout dom/base/nsGlobalWindow.cpp:8916 11 xul.dll nsGlobalWindow::TimerCallback dom/base/nsGlobalWindow.cpp:9261 12 xul.dll nsTimerImpl::Fire xpcom/threads/nsTimerImpl.cpp:425 13 xul.dll nsTimerEvent::Run xpcom/threads/nsTimerImpl.cpp:517 14 xul.dll nsThread::ProcessNextEvent xpcom/threads/nsThread.cpp:609 15 xul.dll mozilla::ipc::MessagePump::Run ipc/glue/MessagePump.cpp:134 16 xul.dll xul.dll@0xb034db 17 xul.dll MessageLoop::RunHandler ipc/chromium/src/base/message_loop.cc:202 18 xul.dll _SEH_epilog4 19 xul.dll MessageLoop::Run ipc/chromium/src/base/message_loop.cc:176 20 xul.dll nsBaseAppShell::Run widget/src/xpwidgets/nsBaseAppShell.cpp:181 21 xul.dll xul.dll@0xb034db 22 xul.dll nsAppShell::Run widget/src/windows/nsAppShell.cpp:243 23 @0x74e8ffff 24 mozcrt19.dll mozcrt19.dll@0xaffff More reports at: http://crash-stats.mozilla.com/report/list?product=Firefox&query_search=signature&query_type=exact&query=&range_value=4&range_unit=weeks&hang_type=any&process_type=any&plugin_field=&plugin_query_type=&plugin_query=&do_query=1&admin=&signature=PopActiveVMFrame
Comment 1•14 years ago
|
||
This appears in the top 10 list in early beta7 stats and on the trunk. Nominating or 2.0.
blocking2.0: --- → ?
Comment 2•14 years ago
|
||
I added the topcrash keyword since it's now in the top 10.
Keywords: topcrash
Assignee | ||
Updated•14 years ago
|
blocking2.0: ? → beta8+
Assignee | ||
Comment 3•14 years ago
|
||
I think this started when I moved activeFrame to the compartment (from thread data). It's certainly the right time frame, and the fact that I modified this particular function is a big hint. The surprise is that that change was supposed to *reduce* this sort of crash. I talked about it with dvander and we decided the likeliest problem is that some call within a JM activation switches compartments, and then as we come back out (usually with an exception, in this crash), the compartment doesn't get reset. We're now on a new compartment, where nothing was pushed, so we crash. JSScript::compartment isn't supposed to change, so changing (Push|Pop)ActiveVMFrame to get its compartment through f.fp->script() instead of f.cx should stop the crash if the above is the issue.
Assignee: general → dmandelin
Status: NEW → ASSIGNED
Assignee | ||
Comment 4•14 years ago
|
||
Attachment #489315 -
Flags: review?(dvander)
Comment on attachment 489315 [details] [diff] [review] Patch >diff --git a/js/src/methodjit/InvokeHelpers.cpp b/js/src/methodjit/InvokeHelpers.cpp >--- a/js/src/methodjit/InvokeHelpers.cpp >+++ b/js/src/methodjit/InvokeHelpers.cpp >@@ -1,9 +1,9 @@ >-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- >+/* -*- mOde: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- > * vim: set ts=4 sw=4 et tw=99: > * > * ***** BEGIN LICENSE BLOCK ***** > * Version: MPL 1.1/GPL 2.0/LGPL 2.1 > * > * The contents of this file are subject to the Mozilla Public License Version > * 1.1 (the "License"); you may not use this file except in compliance with > * the License. You may obtain a copy of the License at >@@ -176,17 +176,17 @@ top: > * throwing an exception. > */ > static void > InlineReturn(VMFrame &f) > { > JSContext *cx = f.cx; > JSStackFrame *fp = f.regs.fp; > >- JS_ASSERT(f.fp() != f.entryFp); >+ JS_ASSERT(f.fp() != f.entryfp); > > JS_ASSERT(!js_IsActiveWithOrBlock(cx, &fp->scopeChain(), 0)); > > Value *newsp = fp->actualArgs() - 1; > newsp[-1] = fp->returnValue(); > cx->stack().popInlineFrame(cx, fp->prev(), newsp); > } > >@@ -226,17 +226,17 @@ RemovePartialFrame(JSContext *cx, JSStac > * overflow f.stackLimit. > */ > void JS_FASTCALL > stubs::HitStackQuota(VMFrame &f) > { > /* Include space to push another frame. */ > uintN nvals = f.fp()->script()->nslots + VALUES_PER_STACK_FRAME; > JS_ASSERT(f.regs.sp == f.fp()->base()); >- if (f.cx->stack().bumpCommitAndLimit(f.entryFp, f.regs.sp, nvals, &f.stackLimit)) >+ if (f.cx->stack().bumpCommitAndLimit(f.entryfp, f.regs.sp, nvals, &f.stackLimit)) > return; > > /* Remove the current partially-constructed frame before throwing. */ > RemovePartialFrame(f.cx, f.fp()); > js_ReportOverRecursed(f.cx); > THROW(); > } > >@@ -264,17 +264,17 @@ stubs::FixupArity(VMFrame &f, uint32 nac > > /* Pop the inline frame. */ > f.fp() = oldfp->prev(); > f.regs.sp = (Value*) oldfp; > > /* Reserve enough space for a callee frame. */ > JSStackFrame *newfp = cx->stack().getInlineFrameWithinLimit(cx, (Value*) oldfp, nactual, > fun, fun->script(), &flags, >- f.entryFp, &f.stackLimit); >+ f.entryfp, &f.stackLimit); > if (!newfp) > THROWV(NULL); > > /* Reset the part of the stack frame set by the caller. */ > newfp->initCallFrameCallerHalf(cx, nactual, flags); > > /* Reset the part of the stack frame set by the prologue up to now. */ > newfp->initCallFrameEarlyPrologue(fun, ncode); >@@ -359,17 +359,17 @@ UncachedInlineCall(VMFrame &f, uint32 fl > JSObject &callee = vp->toObject(); > JSFunction *newfun = callee.getFunctionPrivate(); > JSScript *newscript = newfun->script(); > > /* Get pointer to new frame/slots, prepare arguments. */ > StackSpace &stack = cx->stack(); > JSStackFrame *newfp = stack.getInlineFrameWithinLimit(cx, f.regs.sp, argc, > newfun, newscript, &flags, >- f.entryFp, &f.stackLimit); >+ f.entryfp, &f.stackLimit); > if (JS_UNLIKELY(!newfp)) > return false; > JS_ASSERT_IF(!vp[1].isPrimitive() && !(flags & JSFRAME_CONSTRUCTING), > IsSaneThisObject(vp[1].toObject())); > > /* Initialize frame, locals. */ > newfp->initCallFrame(cx, callee, newfun, argc, flags); > SetValueRangeToUndefined(newfp->slots(), newscript->nfixed); >@@ -555,17 +555,17 @@ js_InternalThrow(VMFrame &f) > pc = FindExceptionHandler(cx); > if (pc) > break; > > // If on the 'topmost' frame (where topmost means the first frame > // called into through js_Interpret). In this case, we still unwind, > // but we shouldn't return from a JS function, because we're not in a > // JS function. >- bool lastFrame = (f.entryFp == f.fp()); >+ bool lastFrame = (f.entryfp == f.fp()); > js_UnwindScope(cx, 0, cx->throwing); > > // For consistency with Interpret(), always run the script epilogue. > // This simplifies interactions with RunTracer(), since it can assume > // no matter how a function exited (error or not), that the epilogue > // does not need to be run. > ScriptEpilogue(f.cx, f.fp(), false); > >diff --git a/js/src/methodjit/MethodJIT.cpp b/js/src/methodjit/MethodJIT.cpp >--- a/js/src/methodjit/MethodJIT.cpp >+++ b/js/src/methodjit/MethodJIT.cpp >@@ -111,24 +111,24 @@ static const size_t STUB_CALLS_FOR_OP_CO > static uint32 StubCallsForOp[STUB_CALLS_FOR_OP_COUNT]; > #endif > > extern "C" void JaegerTrampolineReturn(); > > extern "C" void JS_FASTCALL > PushActiveVMFrame(VMFrame &f) > { >- f.cx->jaegerCompartment()->pushActiveFrame(&f); >+ f.entryfp->script()->compartment->jaegerCompartment->pushActiveFrame(&f); > f.regs.fp->setNativeReturnAddress(JS_FUNC_TO_DATA_PTR(void*, JaegerTrampolineReturn)); > } > > extern "C" void JS_FASTCALL > PopActiveVMFrame(VMFrame &f) > { >- f.cx->jaegerCompartment()->popActiveFrame(); >+ f.entryfp->script()->compartment->jaegerCompartment->popActiveFrame(); > } > > extern "C" void JS_FASTCALL > SetVMFrameRegs(VMFrame &f) > { > f.cx->setCurrentRegs(&f.regs); > } > >@@ -201,17 +201,17 @@ SYMBOL_STRING(JaegerTrampoline) ":" > "movq $0x00007FFFFFFFFFFF, %r14" "\n" > > /* Build the JIT frame. > * rdi = cx > * rsi = fp > * rcx = inlineCallCount > * fp must go into rbx > */ >- "pushq %rsi" "\n" /* entryFp */ >+ "pushq %rsi" "\n" /* entryfp */ > "pushq %rcx" "\n" /* inlineCallCount */ > "pushq %rdi" "\n" /* cx */ > "pushq %rsi" "\n" /* fp */ > "movq %rsi, %rbx" "\n" > > /* Space for the rest of the VMFrame. */ > "subq $0x28, %rsp" "\n" > >@@ -312,17 +312,17 @@ SYMBOL_STRING(JaegerTrampoline) ":" > /* Save non-volatile registers. */ > "pushl %esi" "\n" > "pushl %edi" "\n" > "pushl %ebx" "\n" > > /* Build the JIT frame. Push fields in order, > * then align the stack to form esp == VMFrame. */ > "movl 12(%ebp), %ebx" "\n" /* load fp */ >- "pushl %ebx" "\n" /* entryFp */ >+ "pushl %ebx" "\n" /* entryfp */ > "pushl 20(%ebp)" "\n" /* stackLimit */ > "pushl 8(%ebp)" "\n" /* cx */ > "pushl %ebx" "\n" /* fp */ > "subl $0x1C, %esp" "\n" > > /* Jump into the JIT'd code. */ > "movl %esp, %ecx" "\n" > "call " SYMBOL_STRING_VMFRAME(SetVMFrameRegs) "\n" >@@ -391,17 +391,17 @@ SYMBOL_STRING(InjectJaegerReturn) ":" > "movl 0x1C(%esp), %ebx" "\n" /* f.fp */ > "jmp *%eax" "\n" > ); > > # elif defined(JS_CPU_ARM) > > JS_STATIC_ASSERT(sizeof(VMFrame) == 80); > JS_STATIC_ASSERT(offsetof(VMFrame, savedLR) == (4*19)); >-JS_STATIC_ASSERT(offsetof(VMFrame, entryFp) == (4*10)); >+JS_STATIC_ASSERT(offsetof(VMFrame, entryfp) == (4*10)); > JS_STATIC_ASSERT(offsetof(VMFrame, stackLimit) == (4*9)); > JS_STATIC_ASSERT(offsetof(VMFrame, cx) == (4*8)); > JS_STATIC_ASSERT(offsetof(VMFrame, regs.fp) == (4*7)); > JS_STATIC_ASSERT(offsetof(VMFrame, unused) == (4*4)); > JS_STATIC_ASSERT(offsetof(VMFrame, previous) == (4*3)); > > JS_STATIC_ASSERT(JSFrameReg == JSC::ARMRegisters::r11); > JS_STATIC_ASSERT(JSReturnReg_Data == JSC::ARMRegisters::r1); >@@ -446,33 +446,33 @@ SYMBOL_STRING(JaegerTrampoline) ":" > * [ r11 ] | > * [ r10 ] | > * [ r9 ] | Callee-saved registers. > * [ r8 ] | VFP registers d8-d15 may be required here too, but > * [ r7 ] | unconditionally preserving them might be expensive > * [ r6 ] | considering that we might not use them anyway. > * [ r5 ] | > * [ r4 ] / >- * [ entryFp ] >+ * [ entryfp ] > * [ stkLimit ] > * [ cx ] > * [ regs.fp ] > * [ regs.pc ] > * [ regs.sp ] > * [ unused ] > * [ previous ] > * [ args.ptr3 ] > * [ args.ptr2 ] > * [ args.ptr ] > */ > > /* Push callee-saved registers. */ > " push {r4-r11,lr}" "\n" > /* Push interesting VMFrame content. */ >-" push {r1}" "\n" /* entryFp */ >+" push {r1}" "\n" /* entryfp */ > " push {r3}" "\n" /* stackLimit */ > " push {r0}" "\n" /* cx */ > " push {r1}" "\n" /* regs.fp */ > /* Remaining fields are set elsewhere, but we need to leave space for them. */ > " sub sp, sp, #(4*7)" "\n" > > /* Preserve 'code' (r2) in an arbitrary callee-saved register. */ > " mov r4, r2" "\n" >diff --git a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h >--- a/js/src/methodjit/MethodJIT.h >+++ b/js/src/methodjit/MethodJIT.h >@@ -65,17 +65,17 @@ struct VMFrame > } x; > } u; > > VMFrame *previous; > void *unused; > JSFrameRegs regs; > JSContext *cx; > Value *stackLimit; >- JSStackFrame *entryFp; >+ JSStackFrame *entryfp; > > #if defined(JS_CPU_X86) > void *savedEBX; > void *savedEDI; > void *savedESI; > void *savedEBP; > void *savedEIP; > >diff --git a/js/src/methodjit/Retcon.cpp b/js/src/methodjit/Retcon.cpp >--- a/js/src/methodjit/Retcon.cpp >+++ b/js/src/methodjit/Retcon.cpp >@@ -127,17 +127,17 @@ Recompiler::recompile() > > // Find all JIT'd stack frames to account for return addresses that will > // need to be patched after recompilation. > for (VMFrame *f = script->compartment->jaegerCompartment->activeFrame(); > f != NULL; > f = f->previous) { > > // Scan all frames owned by this VMFrame. >- JSStackFrame *end = f->entryFp->prev(); >+ JSStackFrame *end = f->entryfp->prev(); > for (JSStackFrame *fp = f->fp(); fp != end; fp = fp->prev()) { > // Remember the latest frame for each type of JIT'd code, so the > // compiler will have a frame to re-JIT from. > if (!firstCtorFrame && fp->script() == script && fp->isConstructing()) > firstCtorFrame = fp; > else if (!firstNormalFrame && fp->script() == script && !fp->isConstructing()) > firstNormalFrame = fp; >
Attachment #489315 -
Flags: review?(dvander) → review+
Assignee | ||
Comment 6•14 years ago
|
||
http://hg.mozilla.org/tracemonkey/rev/d6b327f772ca http://hg.mozilla.org/mozilla-central/rev/f30da38f918b I will check that the crash is gone before closing.
Assignee | ||
Comment 7•14 years ago
|
||
It's gone. Please reopen if it recurs in builds after Nov 10.
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Whiteboard: fixed-in-tracemonkey
Updated•13 years ago
|
Crash Signature: [@ PopActiveVMFrame ]
You need to log in
before you can comment on or make changes to this bug.
Description
•