Closed
Bug 729955
Opened 13 years ago
Closed 13 years ago
Debug Crash [@ nsIFrame::GetSize() ]
Categories
(Core :: Layout, defect)
Tracking
()
RESOLVED
FIXED
mozilla14
People
(Reporter: bc, Assigned: mattwoodrow)
References
()
Details
(Keywords: crash, regression, testcase)
Crash Data
Attachments
(2 files, 1 obsolete file)
(deleted),
text/html
|
Details | |
(deleted),
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
1. http://acko.net/blog/this-is-your-brain-on-css/
2. Crash Debug Nightly on Mac, Linux, Windows
I didn't crash with an opt build in my limited testing.
I could reproduce with a saved version but it was very finicky to reduce. I'll try again later.
Operating system: Windows NT
6.1.7601 Service Pack 1
CPU: x86
GenuineIntel family 6 model 37 stepping 1
2 CPUs
Crash reason: EXCEPTION_ACCESS_VIOLATION_READ
Crash address: 0x10
Thread 0 (crashed)
0 xul.dll!nsIFrame::GetSize() [nsIFrame.h : 830 + 0xa]
eip = 0x6ed0e4aa esp = 0x0035b6ac ebp = 0x0035b6b0 ebx = 0x00000001
esi = 0x03f10b68 edi = 0x00000000 eax = 0x00000000 ecx = 0x00000000
edx = 0x00000034 efl = 0x00210246
Found by: given as instruction pointer in context
1 xul.dll!nsDisplayTransform::GetFrameBoundsForTransform(nsIFrame const *) [nsDisplayList.cpp : 2354 + 0xb]
eip = 0x6ed399aa esp = 0x0035b6b8 ebp = 0x0035b6cc
Found by: call frame info
2 xul.dll!GetDeltaToMozPerspectiveOrigin [nsDisplayList.cpp : 2468 + 0x1d]
eip = 0x6ed3a1ec esp = 0x0035b6d4 ebp = 0x0035b774
Found by: call frame info
3 xul.dll!nsDisplayTransform::GetResultingTransformMatrix(nsIFrame const *,nsPoint const &,float,nsRect const *,nsIFrame * *) [nsDisplayList.cpp : 2571 + 0x1a]
eip = 0x6ed39c46 esp = 0x0035b77c ebp = 0x0035ba3c
Found by: call frame info
4 xul.dll!nsDisplayTransform::TransformRectOut(nsRect const &,nsIFrame const *,nsPoint const &,nsRect const *) [nsDisplayList.cpp : 2943 + 0x24]
eip = 0x6ed3b1e1 esp = 0x0035ba44 ebp = 0x0035baa8
Found by: call frame info
related assertions:
###!!! ASSERTION: no placeholder frame for out-of-flow frame: 'Not Reached', file /work/mozilla/builds/nightly/mozilla/layout/generic/nsFrame.cpp, line 7139
###!!! ASSERTION: Can't get delta without a style parent!: 'aFrame->GetParentStyleContextFrame()', file /work/mozilla/builds/nightly/mozilla/layout/base/nsDisplayList.cpp, line 2456
###!!! ASSERTION: no placeholder frame for out-of-flow frame: 'Not Reached', file /work/mozilla/builds/nightly/mozilla/layout/generic/nsFrame.cpp, line 7139
###!!! ASSERTION: Can't get the bounds of a nonexistent frame!: 'aFrame', file /work/mozilla/builds/nightly/mozilla/layout/base/nsDisplayList.cpp, line 2353
Reporter | ||
Comment 1•13 years ago
|
||
###!!! ASSERTION: no placeholder frame for out-of-flow frame: 'Not Reached', file /work/mozilla/builds/nightly/mozilla/layout/generic/nsFrame.cpp, line 7141
###!!! ASSERTION: Can't get delta without a style parent!: 'aFrame->GetParentStyleContextFrame()', file /work/mozilla/builds/nightly/mozilla/layout/base/nsDisplayList.cpp, line 2461
###!!! ASSERTION: no placeholder frame for out-of-flow frame: 'Not Reached', file /work/mozilla/builds/nightly/mozilla/layout/generic/nsFrame.cpp, line 7141
###!!! ASSERTION: Can't get the bounds of a nonexistent frame!: 'aFrame', file /work/mozilla/builds/nightly/mozilla/layout/base/nsDisplayList.cpp, line 2358
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000010
0x05ba9769 in nsIFrame::GetSize (this=0x0) at nsIFrame.h:830
830 nsSize GetSize() const { return nsSize(mRect.width, mRect.height); }
Reporter | ||
Updated•13 years ago
|
Keywords: testcase-wanted → testcase
Comment 2•13 years ago
|
||
Confirmed:
bp-6888d516-f76a-4af6-9b27-7c0d02120309 .
http://hg.mozilla.org/mozilla-central/rev/2f6368ca605e
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20120308 Firefox/13.0a1 ID:20120308031058
Regression window(m-c),
Not crash:
http://hg.mozilla.org/mozilla-central/rev/81f6b9cbb2a9
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0a1) Gecko/20120214 Firefox/13.0a1 ID:20120215021649
Crashes:
http://hg.mozilla.org/mozilla-central/rev/46e22ce549b0
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0a1) Gecko/20120215 Firefox/13.0a1 ID:20120215083849
Pushlog:
http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=81f6b9cbb2a9&tochange=46e22ce549b0
Regression window(m-i),
Not crash:
http://hg.mozilla.org/integration/mozilla-inbound/rev/1db98753a46f
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0a1) Gecko/20120214 Firefox/13.0a1 ID:20120215011955
Crashes:
http://hg.mozilla.org/integration/mozilla-inbound/rev/3884d70d2f7d
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0a1) Gecko/20120214 Firefox/13.0a1 ID:20120215012949
Pushlog:
http://hg.mozilla.org/integration/mozilla-inbound/pushloghtml?fromchange=1db98753a46f&tochange=3884d70d2f7d
Last Good : 1158b09686b7 Matt Woodrow — Bug 721082 - Constify nsIFrame::GetParentStyleContextFrame. r=roc
First bad : b736157e56f6 Matt Woodrow — Bug 721082 - Make perspective-origin relative to the parent elements border box. r=roc
Blocks: 721082
Crash Signature: [@ nsIFrame::GetSize() ] → [@ nsIFrame::GetSize() ]
[@ nsDisplayTransform::GetFrameBoundsForTransform(nsIFrame const*)]
Reporter | ||
Comment 3•13 years ago
|
||
Hey Matt, can you look at this?
Reporter | ||
Updated•13 years ago
|
Keywords: regressionwindow-wanted
Assignee | ||
Updated•13 years ago
|
Assignee: nobody → matt.woodrow
Assignee | ||
Comment 4•13 years ago
|
||
GetParentStyleContextFrame() is returning NULL here, I'm not sure why.
bz: Is this expected? for this to return null, when aFrame->GetStyleContext()->GetParent() is returning a valid style context.
I'm not sure what we should be doing if this is expected, since perspective needs the parents bounding box size.
Comment 5•13 years ago
|
||
What does the frame tree look like here? Which of those frames are we calling GetParentStyleContextFrame() on?
Assignee | ||
Comment 6•13 years ago
|
||
Frame tree: http://pastebin.mozilla.org/1526954
frame: 0x11c128b50
sc: 0x11c127f10
sc->Parent: 0x11aea79b0
Comment 7•13 years ago
|
||
Well, there's nothing in that tree with sc=0x11aea79b0 offhand.
Worse yet, if you look at the frame dump, there is no placeholder corresponding to the Block(section) that I can see. I would have expected to see it as a child of the Block(div) which has as its parent the Block(body), but I don't see any of that stuff in there at all. The Block(html) has a single empty line and that's it. Where did the frames for the <body> go? And when they went away, why didn't the Block(section) go away?
Given the busted frame tree, the null return value from GetParentStyleContextFrame() is "expected"...
Where was that data gathered? Is it possibly in the middle of frame construction?
Assignee | ||
Comment 8•13 years ago
|
||
Looks like frame destruction:
#0 0x00000001016e0bc0 in nsIFrame::GetSize (this=0x0) at nsIFrame.h:830
#1 0x000000010170fbe1 in nsDisplayTransform::GetFrameBoundsForTransform (aFrame=0x0) at nsDisplayList.cpp:2359
#2 0x00000001017161c3 in GetDeltaToMozPerspectiveOrigin (aFrame=0x10ce2ef70, aAppUnitsPerPixel=60) at nsDisplayList.cpp:2471
#3 0x00000001017171b8 in nsDisplayTransform::GetResultingTransformMatrix (aFrame=0x10ce2ef70, aOrigin=@0x7fff5fbf9ea8, aAppUnitsPerPixel=60, aBoundsOverride=0x0, aOutAncestor=0x0) at nsDisplayList.cpp:2575
#4 0x00000001017176ae in nsDisplayTransform::TransformRectOut (aUntransformedBounds=@0x7fff5fbfa0d8, aFrame=0x10ce2ef70, aOrigin=@0x7fff5fbf9ea8, aBoundsOverride=0x0) at nsDisplayList.cpp:2955
#5 0x0000000101845b38 in nsIFrame::InvalidateInternalAfterResize (this=0x10ce2ef70, aDamageRect=@0x7fff5fbfa0d8, aX=0, aY=0, aFlags=0) at nsFrame.cpp:4593
#6 0x0000000101845db5 in nsIFrame::InvalidateInternal (this=0x10ce2ef70, aDamageRect=@0x7fff5fbfa0d8, aX=0, aY=0, aForChild=0x10ce2ef70, aFlags=0) at nsFrame.cpp:4627
#7 0x00000001018116af in nsBlockFrame::InvalidateInternal (this=0x10ce2ef70, aDamageRect=@0x7fff5fbfa0d8, aX=0, aY=0, aForChild=0x0, aFlags=0) at nsBlockFrame.cpp:540
#8 0x000000010183149d in nsIFrame::InvalidateWithFlags (this=0x10ce2ef70, aDamageRect=@0x7fff5fbfa0d8, aFlags=0) at nsFrame.cpp:4522
#9 0x00000001017c892a in nsIFrame::Invalidate (this=0x10ce2ef70, aDamageRect=@0x7fff5fbfa0d8) at nsIFrame.h:2103
#10 0x0000000101842137 in nsIFrame::InvalidateFrameSubtree (this=0x10ce2ef70) at nsFrame.cpp:4708
#11 0x0000000101746e15 in nsFrameManager::RemoveFrame (this=0x11b154800, aListID=mozilla::layout::kAbsoluteList, aOldFrame=0x10ce2ef70) at nsFrameManager.cpp:515
#12 0x00000001018b9de7 in nsPlaceholderFrame::DestroyFrom (this=0x10ce2f008, aDestructRoot=0x119f915b0) at nsPlaceholderFrame.cpp:169
#13 0x00000001018a4884 in nsLineBox::DeleteLineList (aPresContext=0x117c77000, aLines=@0x114239fb8, aDestructRoot=0x119f915b0) at nsLineBox.cpp:406
#14 0x0000000101812651 in nsBlockFrame::DestroyFrom (this=0x114239f40, aDestructRoot=0x119f915b0) at nsBlockFrame.cpp:321
#15 0x000000010185c811 in nsFrameList::DestroyFramesFrom (this=0x1142388d8, aDestructRoot=0x119f915b0) at nsFrameList.cpp:94
#16 0x000000010182bd52 in nsContainerFrame::DestroyFrom (this=0x114238878, aDestructRoot=0x119f915b0) at nsContainerFrame.cpp:250
#17 0x0000000101870f03 in nsHTMLScrollFrame::DestroyFrom (this=0x114238878, aDestructRoot=0x119f915b0) at nsGfxScrollFrame.cpp:125
#18 0x00000001018a4884 in nsLineBox::DeleteLineList (aPresContext=0x117c77000, aLines=@0x119f91628, aDestructRoot=0x119f915b0) at nsLineBox.cpp:406
#19 0x0000000101812651 in nsBlockFrame::DestroyFrom (this=0x119f915b0, aDestructRoot=0x119f915b0) at nsBlockFrame.cpp:321
#20 0x0000000101ad9bf3 in nsIFrame::Destroy (this=0x119f915b0) at nsIFrame.h:582
#21 0x00000001018018cf in nsBlockFrame::DoRemoveFrame (this=0x119f8f870, aDeletedFrame=0x119f915b0, aFlags=2) at nsBlockFrame.cpp:5525
#22 0x0000000101802142 in nsBlockFrame::RemoveFrame (this=0x119f8f870, aListID=mozilla::layout::kPrincipalList, aOldFrame=0x119f915b0) at nsBlockFrame.cpp:5079
#23 0x0000000101746ff4 in nsFrameManager::RemoveFrame (this=0x11b154800, aListID=mozilla::layout::kPrincipalList, aOldFrame=0x119f915b0) at nsFrameManager.cpp:531
#24 0x00000001016dc8a9 in nsCSSFrameConstructor::ContentRemoved (this=0x11b154800, aContainer=0x11a0c99d0, aChild=0x10d81e820, aOldNextSibling=0x0, aFlags=nsCSSFrameConstructor::REMOVE_FOR_RECONSTRUCTION, aDidReconstruct=0x7fff5fbfaa37) at nsCSSFrameConstructor.cpp:7450
#25 0x00000001016db35a in nsCSSFrameConstructor::RecreateFramesForContent (this=0x11b154800, aContent=0x10d81e820, aAsyncInsert=false) at nsCSSFrameConstructor.cpp:9049
#26 0x00000001016dd9bc in nsCSSFrameConstructor::ProcessRestyledFrames (this=0x11b154800, aChangeList=@0x7fff5fbfac70) at nsCSSFrameConstructor.cpp:7893
#27 0x00000001016de591 in nsCSSFrameConstructor::RestyleElement (this=0x11b154800, aElement=0x10d81e820, aPrimaryFrame=0x119f915b0, aMinHint=0, aRestyleTracker=@0x11b1548e8, aRestyleDescendants=true) at nsCSSFrameConstructor.cpp:8006
#28 0x00000001016ba58d in mozilla::css::RestyleTracker::ProcessOneRestyle (this=0x11b1548e8, aElement=0x10d81e820, aRestyleHint=3, aChangeHint=0) at RestyleTracker.cpp:157
#29 0x00000001016b897c in mozilla::css::RestyleTracker::DoProcessRestyles (this=0x11b1548e8) at RestyleTracker.cpp:242
#30 0x00000001016e46b7 in mozilla::css::RestyleTracker::ProcessRestyles (this=0x11b1548e8) at RestyleTracker.h:101
#31 0x00000001016de2a7 in nsCSSFrameConstructor::ProcessPendingRestyles (this=0x11b154800) at nsCSSFrameConstructor.cpp:11569
#32 0x000000010179ba94 in PresShell::FlushPendingNotifications (this=0x11a970800, aType=Flush_InterruptibleLayout) at nsPresShell.cpp:3961
#33 0x00000001017842f8 in PresShell::WillPaint (this=0x11a970800, aWillSendDidPaint=false) at nsPresShell.cpp:7117
#34 0x0000000102238639 in nsViewManager::CallWillPaintOnObservers (this=0x10cd4c880, aWillSendDidPaint=false) at nsViewManager.cpp:1383
#35 0x000000010223b732 in nsViewManager::DispatchEvent (this=0x10cd4c880, aEvent=0x7fff5fbfc348, aView=0x10cd18660, aStatus=0x7fff5fbfc154) at nsViewManager.cpp:777
#36 0x0000000102234ee9 in HandleEvent (aEvent=0x7fff5fbfc348) at nsView.cpp:158
#37 0x000000010323fc74 in nsChildView::DispatchEvent (this=0x10d0b37d0, event=0x7fff5fbfc348, aStatus=@0x7fff5fbfc2e4) at nsChildView.mm:1512
#38 0x00000001032386bc in nsChildView::DispatchWindowEvent (this=0x10d0b37d0, event=@0x7fff5fbfc348) at nsChildView.mm:1522
#39 0x0000000103233d68 in -[ChildView viewWillDraw] (self=0x10d0be9d0, _cmd=0x7fff8412ae1e) at nsChildView.mm:2707
#40 0x00007fff83871c11 in -[NSView viewWillDraw] ()
#41 0x00007fff83871c11 in -[NSView viewWillDraw] ()
#42 0x00007fff83870952 in -[NSView _sendViewWillDrawInRect:clipRootView:suppressRecursion:] ()
#43 0x00007fff8386f6c1 in -[NSView displayIfNeeded] ()
#44 0x00007fff8386f07d in _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints ()
#45 0x00007fff8d379f37 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#46 0x00007fff8d379e96 in __CFRunLoopDoObservers ()
#47 0x00007fff8d34f159 in __CFRunLoopRun ()
#48 0x00007fff8d34eae6 in CFRunLoopRunSpecific ()
#49 0x00007fff8dd813d3 in RunCurrentEventLoopInMode ()
#50 0x00007fff8dd8858f in ReceiveNextEventCommon ()
#51 0x00007fff8dd884ca in BlockUntilNextEventMatchingListInMode ()
#52 0x00007fff838333f1 in _DPSNextEvent ()
#53 0x00007fff83832cf5 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#54 0x000000010320b3ba in -[GeckoNSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] (self=0x100310230, _cmd=0x7fff840cda78, mask=18446744073709551615, expiration=0x422d63c37f00000d, mode=0x7fff7303bae0, flag=1 '\001') at nsAppShell.mm:208
#55 0x00007fff8382f62d in -[NSApplication run] ()
#56 0x000000010320c237 in nsAppShell::Run (this=0x10910eac0) at nsAppShell.mm:795
#57 0x0000000102dee2b2 in nsAppStartup::Run (this=0x10910ca10) at nsAppStartup.cpp:295
#58 0x0000000101285261 in XRE_main (argc=3, argv=0x7fff5fbffab0, aAppData=0x1000081c0) at nsAppRunner.cpp:3703
#59 0x0000000100001362 in do_main (argc=3, argv=0x7fff5fbffab0) at nsBrowserApp.cpp:190
#60 0x0000000100001b7c in main (argc=3, argv=0x7fff5fbffab0) at nsBrowserApp.cpp:277
Comment 9•13 years ago
|
||
Ah, yes. Walking the frame tree during frame destruction seems like a bad idea.
In particular, the sequence of events here is as follows:
1) We end up in nsPlaceholderFrame::DestroyFrom for the placeholder of that out-of-flow
<section>.
2) The link between the out-of-flow and the placeholder is severed.
3) Since the destruct root doesn't contain the out-of-flow, an explicit RemoveFrame call
is made on the out-of-flow.
4) nsFrameManager::RemoveFrame invalidates the frame before removing it (can we nuke that
in bug 539356 or a followup to that bug, perhaps?)
5) Invalidation as of bug 721082 involves looking for style context parents and we lose.
Just adding a null-check seems like it would lead to incorrect invalidation, right?
The simplest fix is probably adding a boolean argument to RemoveFrame to skip the invalidation and invalidating manually in the placeholder teardown code before unhooking the out-of-flow and the placeholder. But even that seems somewhat dangerous, because the frame tree is not exactly in a consistent state here and fundamentally getting the style context parent (as well as invalidation in general!) involve walking around the frame tree.... Maybe it's good enough for now pending item 4 above getting fixed?
5)
(In reply to Boris Zbarsky (:bz) from comment #9)
> 4) nsFrameManager::RemoveFrame invalidates the frame before removing it
> (can we nuke that
> in bug 539356 or a followup to that bug, perhaps?)
Yes, bug 539356 should kill that.
> The simplest fix is probably adding a boolean argument to RemoveFrame to
> skip the invalidation and invalidating manually in the placeholder teardown
> code before unhooking the out-of-flow and the placeholder. But even that
> seems somewhat dangerous, because the frame tree is not exactly in a
> consistent state here and fundamentally getting the style context parent (as
> well as invalidation in general!) involve walking around the frame tree....
> Maybe it's good enough for now pending item 4 above getting fixed?
> 5)
Probably.
Assignee | ||
Comment 11•13 years ago
|
||
(In reply to Boris Zbarsky (:bz) from comment #9)
> Just adding a null-check seems like it would lead to incorrect invalidation,
> right?
Right.
>
> The simplest fix is probably adding a boolean argument to RemoveFrame to
> skip the invalidation and invalidating manually in the placeholder teardown
> code before unhooking the out-of-flow and the placeholder.
Where is the code for this? RemoveFrame already calls InvalidateFrameSubtree() before doing any other work, isn't this enough to invalidate everything?
It seems like the other invalidations called from below this aren't required at all.
Comment 12•13 years ago
|
||
The point is that by the time RemoveFrame is called here (from nsPlaceholderFrame::DestroyFrom) the frame tree is already in an inconsistent state. In particular, trying to find the style parent of the frame the RemoveFrame is called on will crash as in this bug.
So my proposal (again, modulo whatever happens in bug 539356) is that nsPlaceholderFrame::DestroyFrom should do the invalidate _before_ putting the frame tree in an inconsistent state, and tell RemoveFrame to not do the invalidation itself.
Assignee | ||
Comment 13•13 years ago
|
||
Right, got it. I was looking at the earlier RemoveFrame call (#23 in the stack trace).
Assignee | ||
Comment 14•13 years ago
|
||
Fixes the crash for me
Attachment #608206 -
Flags: review?(bzbarsky)
Comment 15•13 years ago
|
||
Comment on attachment 608206 [details] [diff] [review]
Invalidate before destroying the placeholder
I think you forgot to qref...
Attachment #608206 -
Flags: review?(bzbarsky) → review-
Assignee | ||
Comment 16•13 years ago
|
||
Sure did!
Attachment #608206 -
Attachment is obsolete: true
Attachment #608211 -
Flags: review?(bzbarsky)
Updated•13 years ago
|
Attachment #608211 -
Flags: review?(bzbarsky) → review-
Updated•13 years ago
|
Attachment #608211 -
Flags: review- → review+
Assignee | ||
Comment 17•13 years ago
|
||
Comment 18•13 years ago
|
||
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla14
You need to log in
before you can comment on or make changes to this bug.
Description
•