Crash [@ IsPercentageAware] with first-letter, position:fixed, etc

RESOLVED FIXED in mozilla8



9 years ago
7 years ago


(Reporter: martijn.martijn, Assigned: mats)


({crash, testcase})

crash, testcase
Dependency tree / graph
Bug Flags:
in-testsuite +

Firefox Tracking Flags

(blocking2.0 -, status2.0 wanted)


(crash signature)


(5 attachments, 4 obsolete attachments)



9 years ago
Created attachment 457556 [details]

See testcase, which crashes current trunk build, after you've resized the browser window.
0  	xul.dll  	IsPercentageAware  	 layout/generic/nsLineLayout.cpp:671
1 	mozcrt19.dll 	arena_malloc_small 	obj-firefox/memory/jemalloc/crtsrc/jemalloc.c:3734
2 	mozcrt19.dll 	malloc 	obj-firefox/memory/jemalloc/crtsrc/jemalloc.c:5811
3 	xul.dll 	nsTArray_base::EnsureCapacity 	obj-firefox/xpcom/build/nsTArray.cpp:76
4 	xul.dll 	xul.dll@0xbcb30f 	
5 	xul.dll 	nsContinuingTextFrame::Init 	
6 	xul.dll 	xul.dll@0x86e8f 	
7 	xul.dll 	PL_DHashTableOperate 	obj-firefox/xpcom/build/pldhash.c:625
8 	xul.dll 	mozilla::FramePropertyTable::Remove 	layout/base/FramePropertyTable.cpp:148
9 	xul.dll 	mozilla::FrameProperties::Remove 	obj-firefox/dist/include/FramePropertyTable.h:230
10 	xul.dll 	nsContainerFrame::StealOverflowFrames 	layout/generic/nsContainerFrame.h:623
11 	xul.dll 	nsLineLayout::BeginSpan 	layout/generic/nsLineLayout.cpp:435
12 	xul.dll 	nsFirstLetterFrame::Reflow 	layout/generic/nsFirstLetterFrame.cpp:234


9 years ago
blocking2.0: --- → ?
Oh, this is exciting.  The immediate cause of the crash is that we pass a null frame pointer to IsPercentageAware.  And that happens because the nsFirstLetterFrame has no textframe kid but nsFirstLetterFrame::Reflow assumes |kid| is non-null.

Looking at the frame tree, it looks like we have a block frame for the <td> which has a Letter frame containing the first 'm' on the first line.  That Letter frame has a continuation (containing " m"), and that has another continuation (containing " m").  This last also has an overflow list containing the single textframe with "m\u0639" in it, and a next-continuation which is a Letter frame with no kid which has _another_ next-continuation which is a Letter frame with no kid.

We're reflowing this last letter frame.

So it looks like we somehow failed to reflow the Letter frame that should have pulled stuff off the overflow list and destroyed that last empty continuation, right?

Comment 3

8 years ago
There were 122 reported crash incidents for IsPercentageAware in the past
two week period.  I think we should wallpaper (with an assert) the case
where kid == NULL until we think we have fixed this.

Comment 5

8 years ago
Created attachment 507762 [details] [diff] [review]

I don't think this is needed though, because I have found the real bug....
Assignee: nobody → matspal

Comment 6

8 years ago
Created attachment 507764 [details] [diff] [review]
fix v1

After reflowing a first-letter child frame we have
NS_FRAME_IS_COMPLETE(aReflowStatus) and thus we delete all the kid's
This makes a bunch of |this| next-in-flows empty and nsLineLayout::ReflowFrame
only deletes the next-in-flows in the !NS_INLINE_IS_BREAK_BEFORE case
the else-clause just pushes the frame and leaves the empty first-letter
next-in-flows intact.

Let me know if you want the wallpaper as well.  I don't think it should
be necessary.
Attachment #507764 - Flags: review?(roc)
Isn't the nsLineLayout code a bogus optimization? I think it should always delete the next-in-flows of the child even if NS_INLINE_IS_BREAK_BEFORE.

Comment 8

8 years ago
Created attachment 510662 [details] [diff] [review]
fix v2

The crashtest triggers a couple of:
###!!! ASSERTION: Computed overflow area must contain frame bounds: 'aNewSize.width == 0 || aNewSize.height == 0 || aOverflowAreas.Overflow(otype).Contains(nsRect(nsPoint(0,0), aNewSize))', file layout/generic/nsFrame.cpp, line 6144

I'll file that separately.  (TryServer results pending...)

I collected some statistics (loading Alexa top 500 sites).
~7% of nsLineLayout::ReflowFrame calls ends up in the else-block,
of those ~1.7% has a next-in-flow.  In other words, only 0.01% of
nsLineLayout::ReflowFrame calls are affected by the "optimization".

Fwiw, I did a quick hack marking frames where we delete next-in-flows
(in the else-block) and then counting them in
About 96% did call CreateContinuingFrame.
Attachment #507764 - Attachment is obsolete: true
Attachment #510662 - Flags: review?(roc)
Attachment #507764 - Flags: review?(roc)

Comment 9

8 years ago
Created attachment 510663 [details] [diff] [review]
fix v2

Load the right test file...
Attachment #510662 - Attachment is obsolete: true
Attachment #510663 - Flags: review?(roc)
Attachment #510662 - Flags: review?(roc)
+      parent->DeleteNextInFlowChild(mPresContext, kidNextInFlow,
+                                    !NS_INLINE_IS_BREAK_BEFORE(aReflowStatus));

Shouldn't we just be passing "true" for aDeletingEmptyFrames?

Comment 11

8 years ago
If I pass PR_TRUE then nsLayoutUtils::AssertTreeOnlyEmptyNextInFlows says
###!!! ASSERTION: frame tree not empty, but caller reported complete status: 'start == end || IsInLetterFrame(aSubtreeRoot)', file layout/base/nsLayoutUtils.cpp, line 3964
when loading layout/generic/crashtests/586806-1.html

Comment 12

8 years ago
Created attachment 512154 [details]
reduced testcase for the assertion in comment 11

This is a reduced testcase based on layout/generic/crashtests/586806-1.htm

Comment 13

8 years ago
Created attachment 512155 [details]
frame dump + stack for the reduced testcase
Crash Signature: [@ IsPercentageAware]


8 years ago
Blocks: 672080


8 years ago
Attachment #510663 - Attachment is obsolete: true
Attachment #510663 - Flags: review?(roc)

Comment 14

8 years ago
Created attachment 546633 [details]
frame dump #2

Here's a little more detail on what happens leading up the assertion
in nsLayoutUtils::AssertTreeOnlyEmptyNextInFlows.

Where reflowing an inline, 0x7fffd7c353e0 (lime).  It calls
ReflowInlineFrame on its text frame child 0x7fffd7c35450 (yellow)
and the resulting status is INLINE_IS_BREAK_BEFORE, here:
so we break out of the loop and don't reflow any more child frames.
Returning to nsLineLayout::ReflowFrame we now have a reflow status

The previous patch removed the next-in-flow (blue) for the inline (lime)
which caused the assertion, since text frame (red) maps content.
I think removing the next-in-flow in this case is wrong -- when the
reflow status is INLINE_IS_BREAK_BEFORE whether it's also COMPLETE
or INCOMPLETE is irrelevant since we haven't even tried to reflow
all the child frames yet.

I think the real bug is in nsFirstLetterFrame::Reflow (see comment 6)
which caused these first-letter frame continuations to be empty in the
first place.
Attachment #512155 - Attachment is obsolete: true

Comment 15

8 years ago
Created attachment 546634 [details] [diff] [review]
fix v3 (wdiff)

Don't mess with next-in-flows when the status is INLINE_IS_BREAK_BEFORE.
Attachment #546634 - Flags: review?(roc)
Comment on attachment 546634 [details] [diff] [review]
fix v3 (wdiff)

Review of attachment 546634 [details] [diff] [review]:
Attachment #546634 - Flags: review?(roc) → review+

Comment 17

8 years ago
Flags: in-testsuite+
OS: Windows 7 → All
Hardware: x86 → All
Whiteboard: [inbound]
Target Milestone: --- → mozilla8

Comment 18

8 years ago
Last Resolved: 8 years ago
Resolution: --- → FIXED
Whiteboard: [inbound]


7 years ago
Depends on: 698335
You need to log in before you can comment on or make changes to this bug.