Closed Bug 317544 Opened 19 years ago Closed 19 years ago

Crash [@ VerifyContextParent() line 816] involving MathML

Categories

(Core :: Layout, defect)

defect
Not set
major

Tracking

()

VERIFIED FIXED

People

(Reporter: bc, Assigned: sicking)

References

()

Details

(Keywords: crash, fixed1.8.1, verified1.8.0.2, Whiteboard: [sg:critical])

Crash Data

Attachments

(1 file, 4 obsolete files)

Automated StirDOM testing on WinXP with today's FF trunk: http://golem.ph.utexas.edu/~distler/blog/archives/000539.html parameters: 187,217,44,181 + providerFrame 0x00000000 providerIsChild 0x00000000 + aPresContext 0x033d0ce8 + aFrame 0x0365610c + aContext 0xdddddddd + aParentContext 0x00000000 + actualParentContext 0x0364d8e4 VerifyContextParent(nsPresContext * 0x033d0ce8, nsIFrame * 0x0365610c, nsStyleContext * 0xdddddddd, nsStyleContext * 0x00000000) line 816 + 21 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x0365610c, nsStyleContext * 0x00000000) line 856 + 19 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x0364b954, nsStyleContext * 0x00000000) line 874 + 15 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x036506f8, nsStyleContext * 0x00000000) line 881 + 15 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x035e43a0, nsStyleContext * 0x00000000) line 881 + 15 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x035f808c, nsStyleContext * 0x00000000) line 881 + 15 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x03656ec4, nsStyleContext * 0x00000000) line 881 + 15 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x035f8280, nsStyleContext * 0x00000000) line 881 + 15 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x035ec1b8, nsStyleContext * 0x00000000) line 881 + 15 bytes VerifyStyleTree(nsPresContext * 0x033d0ce8, nsIFrame * 0x035e5680, nsStyleContext * 0x034ec3e8) line 881 + 15 bytes nsFrameManager::DebugVerifyStyleTree(nsIFrame * 0x035e5680) line 909 + 22 bytes nsMathMLContainerFrame::PropagateScriptStyleFor(nsIFrame * 0x035e8c8c, int 0x00000000) line 673 nsMathMLContainerFrame::ReResolveScriptStyle(nsMathMLContainerFrame * const 0x035e8cc4, int 0x00000000) line 111 + 16 bytes nsMathMLContainerFrame::ReLayoutChildren(nsIFrame * 0x035e5680) line 910 nsMathMLmathBlockFrame::RemoveFrame(nsMathMLmathBlockFrame * const 0x035e5680, nsIAtom * 0x00ea0f70, nsIFrame * 0x0365610c) line 399 + 9 bytes nsFrameManager::RemoveFrame(nsIFrame * 0x035e5680, nsIAtom * 0x00ea0f70, nsIFrame * 0x0365610c) line 705 DeletingFrameSubtree(nsPresContext * 0x033d0ce8, nsIPresShell * 0x034d10c0, nsFrameManager * 0x034d10dc, nsIFrame * 0x00000000) line 9734 nsCSSFrameConstructor::ContentRemoved(nsIContent * 0x035aeeb8, nsIContent * 0x035af138, int 0x00000000, int 0x00000000) line 9883 + 27 bytes PresShell::ContentRemoved(nsIDocument * 0x034446e0, nsIContent * 0x035aeeb8, nsIContent * 0x035af138, int 0x00000000) line 5185 nsDocument::ContentRemoved(nsIContent * 0x035aeeb8, nsIContent * 0x035af138, int 0x00000000) line 2329 nsHTMLDocument::ContentRemoved(nsIContent * 0x035aeeb8, nsIContent * 0x035af138, int 0x00000000) line 1175 doRemoveChildAt(unsigned int 0x00000000, int 0x00000001, nsIContent * 0x035af138, nsIContent * 0x035aeeb8, nsIDocument * 0x034446e0, nsAttrAndChildArray & {...}) line 2958 nsGenericElement::RemoveChildAt(unsigned int 0x00000000, int 0x00000001) line 2833 + 42 bytes nsGenericElement::RemoveChild(nsGenericElement * const 0x035aeeb8, nsIDOMNode * 0x035af154, nsIDOMNode * * 0x0012ea4c) line 3713 + 17 bytes nsXMLElement::RemoveChild(nsXMLElement * const 0x035aeeb8, nsIDOMNode * 0x035af154, nsIDOMNode * * 0x0012ea4c) line 63 + 20 bytes nsGenericElement::doInsertBefore(nsIDOMNode * 0x035af154, nsIDOMNode * 0x00000000, nsIContent * 0x035de858, nsIDocument * 0x034446e0, nsAttrAndChildArray & {...}, nsIDOMNode * * 0x0012ec90) line 3458 + 63 bytes nsGenericElement::InsertBefore(nsGenericElement * const 0x035de858, nsIDOMNode * 0x035af154, nsIDOMNode * 0x00000000, nsIDOMNode * * 0x0012ec90) line 3012 + 37 bytes nsHTMLDivElement::InsertBefore(nsHTMLDivElement * const 0x035de858, nsIDOMNode * 0x035af154, nsIDOMNode * 0x00000000, nsIDOMNode * * 0x0012ec90) line 56 + 24 bytes nsGenericElement::AppendChild(nsGenericElement * const 0x035de858, nsIDOMNode * 0x035af154, nsIDOMNode * * 0x0012ec90) line 510 nsHTMLDivElement::AppendChild(nsHTMLDivElement * const 0x035de858, nsIDOMNode * 0x035af154, nsIDOMNode * * 0x0012ec90) line 56 + 20 bytes XPTC_InvokeByIndex(nsISupports * 0x035de874, unsigned int 0x00000012, unsigned int 0x00000002, nsXPTCVariant * 0x0012ec80) line 102 XPCWrappedNative::CallMethod(XPCCallContext & {...}, XPCWrappedNative::CallMode CALL_METHOD) line 2139 + 43 bytes XPC_WN_CallMethod(JSContext * 0x032a8de8, JSObject * 0x02d43ff8, unsigned int 0x00000001, long * 0x038db108, long * 0x0012ef54) line 1444 + 14 bytes js_Invoke(JSContext * 0x032a8de8, unsigned int 0x00000001, unsigned int 0x00000000) line 1211 + 23 bytes js_Interpret(JSContext * 0x032a8de8, unsigned char * 0x034dbfea, long * 0x0012fa14) line 3753 + 15 bytes js_Invoke(JSContext * 0x032a8de8, unsigned int 0x00000001, unsigned int 0x00000002) line 1231 + 19 bytes js_InternalInvoke(JSContext * 0x032a8de8, JSObject * 0x02bd9e38, long 0x01a3c338, unsigned int 0x00000000, unsigned int 0x00000001, long * 0x03833e10, long * 0x0012fb94) line 1308 + 20 bytes JS_CallFunctionValue(JSContext * 0x032a8de8, JSObject * 0x02bd9e38, long 0x01a3c338, unsigned int 0x00000001, long * 0x03833e10, long * 0x0012fb94) line 4157 + 31 bytes nsJSContext::CallEventHandler(JSObject * 0x02bd9e38, JSObject * 0x01a3c338, unsigned int 0x00000001, long * 0x03833e10, long * 0x0012fb94) line 1422 + 33 bytes nsGlobalWindow::RunTimeout(nsTimeout * 0x03826f30) line 6219 nsGlobalWindow::TimerCallback(nsITimer * 0x03826fa8, void * 0x03826f30) line 6577 nsTimerImpl::Fire() line 400 + 17 bytes nsTimerManager::FireNextIdleTimer(nsTimerManager * const 0x01a3f308) line 636 nsAppShell::Run(nsAppShell * const 0x00f72a08) line 142 nsAppStartup::Run(nsAppStartup * const 0x00f72968) line 161 + 26 bytes XRE_main(int 0x00000004, char * * 0x003f6d28, const nsXREAppData * 0x0042101c kAppData) line 2289 + 35 bytes main(int 0x00000004, char * * 0x003f6d28) line 61 + 18 bytes mainCRTStartup() line 338 + 17 bytes
Whiteboard: [sg:investigate]
Flags: blocking1.8.0.1?
Summary: Crash [@ VerifyContextParent() line 816] → Crash [@ VerifyContextParent() line 816] involving MathML
Assignee: nobody → rbs
Roger -can you take a look?
Whiteboard: [sg:investigate] → [sg:critical?] references freed memory
Confirmed with a trunk debug build on Mac. I get a similar stack.
OS: Windows XP → All
Hardware: PC → All
Attached patch patch (obsolete) — Splinter Review
With the patch in bug 309120 and this CSS patch, this bug and bug 317545 are also fixed. I once suggested this CSS in bug 307826, but it was not well received because of its poor performance. I don't know any other easy way to say that MathML doesn't allow floating/positioning.
rbs, why is that needed here? Why do we actually crash? Again, if we have a block child of mathml, there is absolutely no reason to prevent floating on its descendants.
> rbs, why is that needed here? Why do we actually crash? Some float related things. A block reflow state isn't been propagated. I could probably get it to work, but it seems clumsy here. > Again, if we have a block child of mathml, there is absolutely no reason to > prevent floating on its descendants. That isn't MathML. You are redefining what MathML is. We already talked about that.
All the same, the patch as written would cause noticeable performance issues any time that stylesheet is loaded. If we want to do something like that, would it suffice to hack it on the frame constructor level (eg push null absolute and float containing blocks any time we process the kids of a MathML frame)?
Attached patch Alternative patch (obsolete) — Splinter Review
So this patch takes an alternative approach. What i'm trying to do is to prevent floating if there is no block reflowstate which is the case when mathml reflows foreign frames. Ideally I would want to do the same for positioned frames, but i'm still trying to figure that out. However this patch alone seems to work as well as attachment 206671 [details] [diff] [review]. One thing i'm worried about is that this might cause us to leak the floating frame since it is never placed. Or will the placeholder take care of that during teardown?
Err.. cancel that, my patch still crashes on this bug, though not bug 317545. Looking into it.
Attached patch Better approach (obsolete) — Splinter Review
This should make us not float descendants of mathml frames. It does this by making sure that we never have a float-containing-block while constructing frames for descendants of mathml. The patch includes a very minimal implementation of IsFrameOfType. It's by no means complete, but rather something we can add to incrementally as we need. Would be good if we could compleatly remove the rule in mathml.css since I think it won't work when xbl is involved. But we can do that in a second patch.
Attachment #207441 - Attachment is obsolete: true
Attachment #207573 - Flags: superreview?
Attachment #207573 - Flags: review?
Attachment #207573 - Flags: superreview?(dbaron)
Attachment #207573 - Flags: superreview?
Attachment #207573 - Flags: review?(bzbarsky)
Attachment #207573 - Flags: review?
Comment on attachment 207573 [details] [diff] [review] Better approach Yeah, I like this.
Attachment #207573 - Flags: review?(bzbarsky) → review+
Need this landed on the trunk if it's going to make the branches. Minusing for .0.1 because getting it in doesn't seem like it's going to happen, but will consider approving a tested patch if it happens soon.
Flags: blocking1.8.1?
Flags: blocking1.8.0.2?
Flags: blocking1.8.0.1?
Flags: blocking1.8.0.1-
Whiteboard: [sg:critical?] references freed memory → [sg:critical?] need sr=dbaron
Comment on attachment 207573 [details] [diff] [review] Better approach Could you add a comment above GetAbsoluteContainingBlock and GetFloatContainingBlock in nsCSSFrameConstructor.h that those two functions are designed to restore state that would have been created on the stack in cases where we start frame construction from a non-root element, and therefore they must match the PushFloatContainingBlock / PushAbsoluteContainingBlock calls that we do elsewhere. (And perhaps a similar comment around the definitions of PushFloatContainingBlock and PushAbsoluteContainingBlock.) I'm not entirely happy with the idea that things with style data that say they're a float just don't float. The only case that already pushes a null float containing block this is svg:foreignObject, which is currently #ifdef-ed out. What have you done to ensure that we don't get confused in this case. I'm particularly worried about callers of nsStyleDisplay::IsFloating that assume that a true result means that the frame is out-of-flow.
It should also be documented somewhere what pushing a null float containing block means. I don't really even know, and I'm rather surprised that it doesn't crash.
So David and I talked about that this might not be the best solution given the number of places where we call IsFloating(). The alternative approach I'm going to try is to strategically place block frames in strategic places to maintain all invariants we're expecting.
Note that places that call IsFloating() might already have issues in XUL documents and such...
But yeah, for branch it may be better to not push null. :(
Attachment #207573 - Flags: superreview?(dbaron) → superreview-
So I looked at the approach in attachment 207573 [details] [diff] [review] some more (since the wrap-in-block approach is quite hard, we can't simply always wrap all children in a single block, sometimes we need separate blocks for each child, such as for mfrac). I thought about going with attachment 207573 [details] [diff] [review], but making it so that if nsFrameConstructorState::AddChild gets a frame that should be floated but there is no floating-container we kill the frame rather then making it not float. However, there are already quite a few places where we push a null floating or absolute container. So I'm afraid that we would be killing a few more frames then just for mathml. But since we are already pushing null containers so often I'm wondering if it isn't safe to do it for mathml too. So I looked at all callers of IsFloating() (there are actually very few) and it seems like all but two should be safe. And the last two might be safe too, but I don't know enough to tell. The two callers are: http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/tables/nsTableOuterFrame.cpp&rev=3.288&mark=1901#1890 http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/tables/nsTableRowFrame.cpp&rev=3.372&mark=1030#1020 Would be great if someone could look to see if these could deal with IsFloating() frames that don't actually float.
Where else do we push null containers other than the ifdef-ed-out case for svg:foreignObject?
We do it in the following cases: 1) XUL effectivly does it by saying that no xul frames can be floated. So you can have xul frames that are IsFloating() without being floating. 2) When the root frame is a table frame. 3) In ConstructRootFrame when calling BeginBuildingScrollFrame 4) In CreateContinuingTableFrame uses a null floating containiner
Attached patch Updated with dbarons comments (obsolete) — Splinter Review
Me and dbaron talked about how to do this and concluded that this patch might be the best we can do for now. Placing extra frames around content as described in comment 14 is how mathml used to deal with foregin frames and it turned out to be RealHard to get to work.
Assignee: rbs → bugmail
Attachment #206671 - Attachment is obsolete: true
Attachment #207573 - Attachment is obsolete: true
Status: NEW → ASSIGNED
Attachment #208888 - Flags: superreview?
Attachment #208888 - Flags: superreview? → superreview?(dbaron)
Comment on attachment 208888 [details] [diff] [review] Updated with dbarons comments >Index: base/nsCSSFrameConstructor.cpp >+ // logic in GetFloatContainingBlock. > void PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock, > nsFrameConstructorSaveState& aSaveState); Comment should refer to GetAbsoluteContainingBlock. > // Function to push the existing float containing block state and >- // create a new scope >+ // create a new scope. Code that uses this function should get matching >+ // logic in GetFloatContainingBlock. >+ // Pushing a null float containing block forbids any frames from being >+ // floated until a new float containing block is pushed. Could you add an XXX comment that we ought to get rid of the use of null float containing blocks? >+ nsFrameConstructorSaveState saveState; >+ aState.PushFloatContainingBlock(nsnull, saveState, PR_FALSE, PR_FALSE); Could you comment here why you're doing this: to forbid floating within MathML. >Index: generic/nsIFrame.h >+ virtual PRBool IsFrameOfType(PRUint32 aFlags) const >+ { >+ return PR_FALSE; >+ } Should be !aFlags, as I said in bug 310436 comment 16. sr=dbaron
Attachment #208888 - Flags: superreview?(dbaron) → superreview+
Checked in on trunk, once this has baked there for a while we should consider taking this for the branches too
Attached patch Final versionSplinter Review
This is what was checked in. Note that it depends on the patch in bug 310436
Attachment #208888 - Attachment is obsolete: true
marking fixed since it should be fixed on trunk
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
*** Bug 317545 has been marked as a duplicate of this bug. ***
Whiteboard: [sg:critical?] need sr=dbaron → [sg:critical] uses freed memory, at least in bug 317545 (dup of this)
Flags: blocking1.8.0.2? → blocking1.8.0.2+
Comment on attachment 209640 [details] [diff] [review] Final version Asking for approval for branches. This has been on trunk for a while and hasn't caused any regressions.
Attachment #209640 - Flags: approval1.8.0.2?
Attachment #209640 - Flags: approval-branch-1.8.1?(dbaron)
Attachment #209640 - Flags: approval-branch-1.8.1?(dbaron) → approval-branch-1.8.1+
Comment on attachment 209640 [details] [diff] [review] Final version approved for 1.8.0 branch, a=dveditz
Attachment #209640 - Flags: approval1.8.0.2? → approval1.8.0.2+
Depends on: 310436
Comment on attachment 209640 [details] [diff] [review] Final version Is there still time to take this on the old branches? If so I think we should. I'll also have to include some parts of the previous attachment in this bug (with dbarons commends addressed of course), since I can't rely on bug 310436 to provide them.
Attachment #209640 - Flags: approval1.7.13?
Attachment #209640 - Flags: approval-aviary1.0.8?
Marking [rft-dl] (ready for testing in Firefox 1.5.0.2 release candidates). Test case info is in comment 0 (fuzz testing tool url and parameters)
Whiteboard: [sg:critical] uses freed memory, at least in bug 317545 (dup of this) → [sg:critical] uses freed memory, at least in bug 317545 (dup of this) [rft-dl]
v.fixed on 1.8.0 branch with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060301 Firefox/1.5.0.1, no crashes with the stack signatures in this bug, BUT a new crash that might be related (bug 329044).
Comment on attachment 209640 [details] [diff] [review] Final version Not considered blocking (at least not nominated) Too late for 1.0.8/1.7.13 as these were closed for non-blockers a while ago. "?"ing for 1.0.9.
Attachment #209640 - Flags: approval1.7.13?
Attachment #209640 - Flags: approval1.7.13-
Attachment #209640 - Flags: approval-aviary1.0.9?
Attachment #209640 - Flags: approval-aviary1.0.8?
Attachment #209640 - Flags: approval-aviary1.0.8-
sicking, did this ever land on the 1.8 branch?
The patch does fix probably-exploitable crashes. But if it's too late for 1.0.8 lets try for 1.0.9
Flags: blocking1.7.14?
Flags: blocking-aviary1.0.9?
> sicking, did this ever land on the 1.8 branch? No, i havn't gone through and landed my fuzz patches for 1.8.1 yet.
This needs to land on the 1.8 branch ASAP.
This patch seems to depend on the patch for bug 307826...
Please land for 1.8.1
Flags: blocking1.8.1? → blocking1.8.1+
Whiteboard: [sg:critical] uses freed memory, at least in bug 317545 (dup of this) [rft-dl] → [checkin needed] [sg:critical] uses freed memory, at least in bug 317545 (dup of this) [rft-dl]
checked in on the 1.8 branch
Keywords: fixed1.8.1
Whiteboard: [checkin needed] [sg:critical] uses freed memory, at least in bug 317545 (dup of this) [rft-dl] → [sg:critical] uses freed memory, at least in bug 317545 (dup of this) [rft-dl]
testing with an early stirdom (see url) 1.8 20060823 linux nightly crash tb22483714. 1.8 20060824 linux nightly crash tb22484775. @IncrementalReflow::AddCommand() mozilla/layout/base/nsPresShell.cpp, line 817] 1.8 20060824 winxp nightly crash TB22484873Z @IncrementalReflow::AddCommand mozilla/layout/base/nsPresShell.cpp, line 938] 1.8 20060823 winxp debug crash. @nsIFrame::GetStateBits() Line 817 (null |this|) lots of ###!!! ASSERTION: dangling frame without a content node: 'content', file f:/work /mozilla/builds/ff/2.0/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp, line 19 followed by ###!!! ASSERTION: null target frame: 'mTargetFrame != nsnull', file f:/work/mozi lla/builds/ff/2.0/mozilla/layout/generic/nsHTMLReflowCommand.cpp, line 94 ###!!! ASSERTION: reflow command with no target: 'frame != nsnull', file f:/work /mozilla/builds/ff/2.0/mozilla/layout/base/nsPresShell.cpp, line 929 1.9 20060824 linux nightly no crash 1.9 20060824 linux debug no crash 1.9 20060824 winxp nightly no crash 1.9 20060824 winxp debug no crash interesting asserts though. verified fixed 1.9
Status: RESOLVED → VERIFIED
> ###!!! ASSERTION: null target frame: 'mTargetFrame != nsnull', file Hmm.... what about on the reflow branch, where reflow commands are gone?
(In reply to comment #40) > > ###!!! ASSERTION: null target frame: 'mTargetFrame != nsnull', file > > Hmm.... what about on the reflow branch, where reflow commands are gone? > I don't see that assertion on windows but crash with a deleted |this| in nsStyleContext::AddRef()
Is there a bug on that crash?
So what exactly landed on branch? I'm getting merge conflicts trying to merge various things to branch, because apparently the branch version of this patch was somewhat different?
Whiteboard: [sg:critical] uses freed memory, at least in bug 317545 (dup of this) [rft-dl] → [sg:critical] contains 306663 testcase
Clearing stale requests.
Flags: blocking1.7.14?
Flags: blocking-aviary1.0.9?
Crash Signature: [@ VerifyContextParent() line 816]
Whiteboard: [sg:critical] contains 306663 testcase → [sg:critical] Embargo until fuzzers public (contains 306663 testcase)
Whiteboard: [sg:critical] Embargo until fuzzers public (contains 306663 testcase) → [sg:critical] Embargo until fuzzers public (URL field history contains 306663 testcase)
Group: core-security → core-security-release
Whiteboard: [sg:critical] Embargo until fuzzers public (URL field history contains 306663 testcase) → [sg:critical]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: