Closed Bug 307277 Opened 20 years ago Closed 20 years ago

crash [@ DoDeletingFrameSubtree]

Categories

(Core :: Layout, defect)

defect
Not set
critical

Tracking

()

RESOLVED FIXED

People

(Reporter: jruderman, Assigned: MatsPalmgren_bugz)

References

Details

(Keywords: crash, verified1.8, Whiteboard: [sg:critical?])

Crash Data

Attachments

(2 files, 1 obsolete file)

Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.9a1) Gecko/20050906 Firefox/1.6a1 Testcase crashes while status bar says "900". Filing as security-sensitive because the unsimplified testcase uses code from bug 306663.
Attached file testcase (not reduced)
TB9097333E
Severity: normal → critical
Keywords: crash
Blocks: stirdom
The problem is that we have a float with a wrong parent (or it's on the wrong frame's float list). Like this: Block 1 Block 2 <--- <Float-list> | Frame::mParent --- Then we do ContentRemoved() which tries to remove the frame from its parent: http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/base/nsCSSFrameConstructor.cpp&rev=1.1126&root=/cvsroot&mark=9752-9753#9732 which ends up doing just Destroy() since it can't find the frame in 'mFloats': http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/generic/nsBlockFrame.cpp&rev=3.737&root=/cvsroot&mark=5378,5410-5412#5377 Later when we do DoDeletingFrameSubtree() on Block 1 we will find the deleted float in its 'mFloats'... So, a pretty simple wallpaper for this bug is look at the ancestors' 'mFloats' in nsBlockFrame::RemoveFloat() and remove it from there (and assert). This is in case we can't find the real bug in nsCSSFrameConstructor... So far, I have tracked down the bad call that inserts the float to here: http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/base/nsCSSFrameConstructor.cpp&rev=1.1126&root=/cvsroot&mark=1416,1444-1446#1415 Maybe we should assert (in nsBlockFrame) that we have a correct parent pointer when an out-of-flow frame is added so we will see these errors earlier...
OS: MacOS X → All
Hardware: Macintosh → All
FWIW: 0xbfffc7e4::nsFrameConstructorState float CB 0x8a60334 [...] Created placeholderFrame=0x8ccde08 for aFrame=0x8ccddb4 0xbfffb6b4::nsFrameConstructorState float CB 0x8cce310 MoveChildrenTo 1 blockFrame=0x8cce310 GetFloatContainingBlock(blockFrame)=0x8cce310 AdjustFloatParentPtrs 0x8ccba5c -> 0x8cce310 (placeholder 0x8ccde08, float 0x8ccddb4) 0xbfffb6b4::~nsFrameConstructorState float CB 0x8cce310 MoveChildrenTo 1 DONE ProcessFrameInsertions: state=0xbfffc7e4, containingBlock(0x8ccba5c)->SetInitialChildList firstNewFrame=0x8ccddb4 uh oh, GetFloatContainingBlock(firstNewFrame->GetParent())=0x8cce310 != containingBlock=0x8ccba5c SetInitialChildList: float list for 0x8ccba5c: ###!!! ASSERTION: wrong parent: 'f->GetParent() == me', file nsBlockFrame.cpp, line 2038 Break: at file nsBlockFrame.cpp, line 2038 So, we have a nested nsFrameConstructorState, in the inner we do AdjustFloatParentPtrs() then we pop and in the outer we do aFrameItems.containingBlock->SetInitialChildList() on the old CB. Maybe we need to update 'containingBlock' in parent states when we do AdjustFloatParentPtrs() or maybe just call GetFloatContainingBlock() again in the outer state so we add to the right frame? Is the following comment relevant here? http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/base/nsCSSFrameConstructor.cpp&rev=1.1126&root=/cvsroot&mark=12972-12978#12965
What it sounds like is that we should move the still-pending floats whose parents we adjust from the "outer" frame constructor state to the inner "one". Mats, do you think you can do that, or should I go for it?
> Is the following comment relevant here? Yes, indeed. So the calls to MoveChildrenTo from nsCSSFrameConstructor::ConstructInline should have the invariant that the only floats they mess with are ones that are on the float list of ConstructInline's aState. The other calls to MoveChildrenTo are from SplitToContainingBlock, and those do no reparenting (and that method is about to die on trunk anyway). So I think what I suggest in comment 5 should work -- every float placeholder we hit in MoveChildrenTo when aState is non-null should correspond (in the same order, even!) to the list of floats in ConstructInline's state. We should probably pass that list in in addition to the state itself so that MoveChildrenTo can remove frames from it and move them to the "inner" state instead.
OK, I will make an attempt at that...
Yes, that seems to work fine, it hasn't crashed in 15 minutes now... (it crashed instantly before). I'm seeing quite a bit of this assertion though: ###!!! ASSERTION: uh oh. the block we need to reframe has no parent!: 'Error', file nsCSSFrameConstructor.cpp, line 13335 and once or twice, this one: ###!!! ASSERTION: no last inline frame: 'PR_FALSE', file nsCSSFrameConstructor.cpp, line 8922
Assignee: nobody → mats.palmgren
Attached patch Patch rev. 1 (obsolete) — Splinter Review
Attachment #196391 - Flags: superreview?(bzbarsky)
Attachment #196391 - Flags: review?(bzbarsky)
Comment on attachment 196391 [details] [diff] [review] Patch rev. 1 >Index: layout/base/nsCSSFrameConstructor.cpp >+ // Move the float from the outer state to the inner when reparenting, bug 307277. >+ if (outOfFlowFrame->GetParent() != parent) { Is this test ever false here? I don't see how it could be, but maybe I'm missing something? If you replace that test with an assert that the two are in fact not equal, does that assert trigger in this testcase? If it doesn't, I think we should go with the assert instead of the test. Other than that, looks great. Thanks for doing this!
Attachment #196391 - Flags: superreview?(bzbarsky)
Attachment #196391 - Flags: superreview+
Attachment #196391 - Flags: review?(bzbarsky)
Attachment #196391 - Flags: review+
Comment on attachment 196391 [details] [diff] [review] Patch rev. 1 >Index: layout/base/nsCSSFrameConstructor.cpp >+ // Move the float from the outer state to the inner when reparenting, bug 307277. >+ if (outOfFlowFrame->GetParent() != parent) { Is this test ever false here? I don't see how it could be, but maybe I'm missing something? If you replace that test with an assert that the two are in fact not equal, does that assert trigger in this testcase? If it doesn't, I think we should go with the assert instead of the test. Other than that, looks great. Thanks for doing this!
Attached patch Patch rev. 2Splinter Review
(only changes in AdjustFloatParentPtrs() compared to rev. 1) The comment "Update the parent pointer for outOfFlowFrame *if* it's ..." lead me to believe we could have some floats already on the inner CB. The assertion agrees with you that this is not the case ;-) Other than that, I added a PRECONDITION and removed a null-check on 'outOfFlowFrame' and a couple of formatting changes.
Attachment #196391 - Attachment is obsolete: true
Attachment #196421 - Flags: superreview?(bzbarsky)
Attachment #196421 - Flags: review?(bzbarsky)
Comment on attachment 196421 [details] [diff] [review] Patch rev. 2 >Index: layout/base/nsCSSFrameConstructor.cpp > AdjustFloatParentPtrs(nsIFrame* aFrame, >+ // Update the parent pointer for outOfFlowFrame since it's s/it's/its/ >+ // recursion of the SplitToContainingBlock will propagate the bit. Note that this comment has changed on trunk; the patch will need to be merged accordingly... (and a branch version of the patch will be needed). >@@ -13374,34 +13406,34 @@ nsCSSFrameConstructor::SplitToContaining This method is gone on trunk (but the branch version of the patch will need this change). r+sr=bzbarsky.
Attachment #196421 - Flags: superreview?(bzbarsky)
Attachment #196421 - Flags: superreview+
Attachment #196421 - Flags: review?(bzbarsky)
Attachment #196421 - Flags: review+
This looks like it fixes bug 266971 too, no?
Blocks: 266971
Checked in to trunk at 2005-09-20 16:00 PDT
Comment on attachment 196421 [details] [diff] [review] Patch rev. 2 Re comment 13: > (and a branch version of the patch will be needed) Boris, this patch applies cleanly to the branch, did you think other adjustments were needed? (besides the code comments)
Attachment #196421 - Flags: approval1.8b5?
No, just the code comments. All I meant is that the trunk version wouldn't apply to branch, so the code comments would need to be addressed there separately.
Attachment #196421 - Flags: approval1.8b5? → approval1.8b5+
Flags: blocking1.8b5+
Comment on attachment 196421 [details] [diff] [review] Patch rev. 2 Checked in to MOZILLA_1_8_BRANCH at 2005-09-21 15:15 PDT -> FIXED
Status: NEW → RESOLVED
Closed: 20 years ago
Keywords: fixed1.8
Resolution: --- → FIXED
Depends on: 310505
no crash with the testcase in firefox 1.5 rc2 winxp/linux. Can someone with a Mac verify this an mark verified1.8?
Verified fixed on the Gecko 1.8 branch: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8) Gecko/20051108 Firefox/1.5.
Keywords: fixed1.8verified1.8
Flags: testcase+
Whiteboard: [sg:critical?]
Group: security
Summary: StirDOM/csszen crash [@ DoDeletingFrameSubtree] → crash [@ DoDeletingFrameSubtree]
Flags: in-testsuite+ → in-testsuite?
Crash Signature: [@ DoDeletingFrameSubtree]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: