WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED WONTFIX
Bug 111074
REGRESSION(
r141450
): failed ASSERT in FrameView::scheduleRelayout()
https://bugs.webkit.org/show_bug.cgi?id=111074
Summary
REGRESSION(r141450): failed ASSERT in FrameView::scheduleRelayout()
Alberto Garcia
Reported
2013-02-28 06:30:03 PST
I have a crash because of this failed assertion in FrameView::scheduleRelayout(): ASSERT(m_frame->view() == this) This seems to have been introduced in
r141450
, which was the fix for
bug 107922
. I cannot reproduce the crash after reverting that patch. The call to frameView->setUseFixedLayout(useFixedLayout) in Frame::createView() triggers a call to scheduleRelayout() while m_view is 0. Here's the backtrace: #0 WebCore::FrameView::scheduleRelayout (this=0x80a2d18) at /home/berto/devel/code/webkit/Source/WebCore/page/FrameView.cpp:2312 #1 0x7c8ec55a in WebCore::RenderObject::scheduleRelayout (this=0x8233890) at /home/berto/devel/code/webkit/Source/WebCore/rendering/RenderObject.cpp:2650 #2 0x7c8e46ce in WebCore::RenderObject::markContainingBlocksForLayout ( this=0x8233890, scheduleRelayout=true, newRoot=0x0) at /home/berto/devel/code/webkit/Source/WebCore/rendering/RenderObject.cpp:709 #3 0x78e2b104 in WebCore::RenderObject::setNeedsLayout (this=0x8233890, needsLayout=true, markParents=WebCore::MarkContainingBlockChain) at /home/berto/devel/code/webkit/Source/WebCore/rendering/RenderObject.h:1191 #4 0x7c626a1a in WebCore::FrameView::setNeedsLayout (this=0x82b8b88) at /home/berto/devel/code/webkit/Source/WebCore/page/FrameView.cpp:2439 #5 0x7c625b5e in WebCore::FrameView::contentsResized (this=0x82b8b88) at /home/berto/devel/code/webkit/Source/WebCore/page/FrameView.cpp:2122 #6 0x7c6b02ec in WebCore::ScrollView::setUseFixedLayout (this=0x82b8b88, enable=true) at /home/berto/devel/code/webkit/Source/WebCore/platform/ScrollView.cpp:324 #7 0x7c61875e in WebCore::Frame::createView (this=0x80a6f38, viewportSize=..., backgroundColor=..., transparent=false, fixedReportedSize=..., fixedLayoutSize=..., fixedVisibleContentRect=..., useFixedLayout=true, horizontalScrollbarMode=WebCore::ScrollbarAlwaysOff, horizontalLock=true, verticalScrollbarMode=WebCore::ScrollbarAlwaysOff, verticalLock=true) at /home/berto/devel/code/webkit/Source/WebCore/page/Frame.cpp:804 ...
Attachments
Patch
(1.14 KB, patch)
2013-03-04 01:09 PST
,
Alberto Garcia
darin
: review-
darin
: commit-queue-
Details
Formatted Diff
Diff
Alternative patch
(13.68 KB, patch)
2013-03-13 12:31 PDT
,
Chris Dumez
simon.fraser
: review-
Details
Formatted Diff
Diff
another alternative
(2.22 KB, patch)
2013-04-04 07:27 PDT
,
Mikhail Pozdnyakov
simon.fraser
: review-
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Alexandre Elias
Comment 1
2013-02-28 11:33:50 PST
Looks like the problem is the FrameView has not yet been attached to the Frame. Does it fix the problem if in Frame::createView, you move the three fixedLayout...() calls after setView(frameView)? That would be my proposed fix. By the way, what port is this?
Alberto Garcia
Comment 2
2013-03-01 03:17:37 PST
(In reply to
comment #1
)
> Looks like the problem is the FrameView has not yet been attached to > the Frame. Does it fix the problem if in Frame::createView, you > move the three fixedLayout...() calls after setView(frameView)? > That would be my proposed fix.
Hmmm... that doesn't seem to solve the problem. Now the new FrameView is attached to the frame, but during FrameView::setNeedsLayout() the renderView's setNeedsLayout() is also called. That ends up in RenderObject::scheduleRelayout(), the pointer to the FrameView there is different from the one we just created, so the assertion also fails. #0 0x7c826352 in WebCore::FrameView::scheduleRelayout (this=0x80a2c20) at /home/berto/devel/code/webkit/Source/WebCore/page/FrameView.cpp:2313 #1 0x7caec582 in WebCore::RenderObject::scheduleRelayout (this=0x8247360) at /home/berto/devel/code/webkit/Source/WebCore/rendering/RenderObject.cpp:2650 #2 0x7cae46f6 in WebCore::RenderObject::markContainingBlocksForLayout ( this=0x8247360, scheduleRelayout=true, newRoot=0x0) at /home/berto/devel/code/webkit/Source/WebCore/rendering/RenderObject.cpp:709 #3 0x7952b104 in WebCore::RenderObject::setNeedsLayout (this=0x8247360, needsLayout=true, markParents=WebCore::MarkContainingBlockChain) at /home/berto/devel/code/webkit/Source/WebCore/rendering/RenderObject.h:1191 #4 0x7c826a42 in WebCore::FrameView::setNeedsLayout (this=0x8468210) at /home/berto/devel/code/webkit/Source/WebCore/page/FrameView.cpp:2438 #5 0x7c825bae in WebCore::FrameView::contentsResized (this=0x8468210) at /home/berto/devel/code/webkit/Source/WebCore/page/FrameView.cpp:2124 #6 0x7c8b0314 in WebCore::ScrollView::setUseFixedLayout (this=0x8468210, enable=true) at /home/berto/devel/code/webkit/Source/WebCore/platform/ScrollView.cpp:324 #7 0x7c8187b4 in WebCore::Frame::createView (this=0x80a6cf0, viewportSize=..., backgroundColor=..., transparent=false, fixedReportedSize=..., fixedLayoutSize=..., fixedVisibleContentRect=..., useFixedLayout=true, horizontalScrollbarMode=WebCore::ScrollbarAlwaysOff, horizontalLock=true, verticalScrollbarMode=WebCore::ScrollbarAlwaysOff, verticalLock=true) at /home/berto/devel/code/webkit/Source/WebCore/page/Frame.cpp:808 #8 0x7955706c in WebCore::FrameLoaderClientBlackBerry::transitionToCommittedForNewPage (this=0x8091518) at /home/berto/devel/code/webkit/Source/WebKit/blackberry/WebCoreSupport/FrameLoaderClientBlackBerry.cpp:470 #9 0x7c74064c in WebCore::FrameLoader::transitionToCommitted (this=0x80a6d40, cachedPage=...) at /home/berto/devel/code/webkit/Source/WebCore/loader/FrameLoader.cpp:1893
> By the way, what port is this?
BlackBerry
Alexandre Elias
Comment 3
2013-03-03 12:53:30 PST
So far I haven't been able to figure out via code inspection why the RenderView's frame may be different, so I'm not sure about the root cause. But to address this regression, one thing we can do is delete the "contentsResized();" call from "ScrollView::setUseFixedLayout()". I only need to keep the other one in "ScrollView::setFixedLayoutSize()". Could you check that fixes it?
Alexandre Elias
Comment 4
2013-03-03 13:06:24 PST
On second thought, before we do that, a better fix would be to add "if (!frame()->view()) return;" to "contentsResized()". I believe it should work if you move back the calls in Frame::createView() to their original place. Please give that a try.
Alberto Garcia
Comment 5
2013-03-04 01:09:25 PST
Created
attachment 191168
[details]
Patch (In reply to
comment #4
)
> On second thought, before we do that, a better fix would be to add > "if (!frame()->view()) return;" to "contentsResized()".
Hey, this seems to solve the problem, thanks!
James Robinson
Comment 6
2013-03-04 08:51:03 PST
Comment on
attachment 191168
[details]
Patch What's the testcase?
Xan Lopez
Comment 7
2013-03-04 23:29:03 PST
(In reply to
comment #6
)
> (From update of
attachment 191168
[details]
) > What's the testcase?
Maybe Alexandre can suggest what kind of test we could write for this particular regression.
Alexandre Elias
Comment 8
2013-03-04 23:41:58 PST
Seems impossible to test with a layout test given that it only happens in the Frame constructor with port-specific arguments. If Blackberry has a unit test system that runs on EWS, you can construct a Frame there, but AFAIK you don't, so I would be fine with submitting as is.
Darin Adler
Comment 9
2013-03-06 09:43:04 PST
Comment on
attachment 191168
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=191168&action=review
review- because this is too mysterious to do without a comment, and is probably not exactly the right fix
> Source/WebCore/page/FrameView.cpp:2061 > + if (!frame()->view()) > + return;
The strange thing about this is that we could add a check like this to all FrameView functions. We need a rule to tell us which ones need this. It’s particularly important because you are not contributing a test for this, so no one would be able to tell functions that need this kind of check from functions that don’t. Further, it’s non-obvious why taking a round trip to check for null is the right thing here. This needs a comment, not just the code, because it’s non-obvious. Further, maybe it should be a check for frame()->view() == this instead of frame()->view() being non-null. What’s special about contentsResized that means this is needed? Maybe the check belongs at the caller instead of inside this function?
Darin Adler
Comment 10
2013-03-06 09:43:26 PST
Comment on
attachment 191168
[details]
Patch A step in the right direction, but still needs work.
Alexandre Elias
Comment 11
2013-03-06 12:36:30 PST
There's a similar if() statement in FrameView::visibleContentsResized() for the same reason (ends up getting called from Frame::createView), with a comment. So this fix is at least consistent with what was there already (I agree it's somewhat strange though).
Alberto Garcia
Comment 12
2013-03-07 02:31:54 PST
(In reply to
comment #9
)
> review- because this is too mysterious to do without a comment, and > is probably not exactly the right fix
I think your objections are reasonable. If I find more information that can make us come up with a better fix I'll post it here. One thing to note, though, is that if I compile with assertions disabled then everything seems to work normally. Maybe that is a false assertion in FrameView::scheduleRelayout() ?
Simon Fraser (smfr)
Comment 13
2013-03-07 09:13:51 PST
I don't think it's a false assertion. It implies that something happened that is unexpected.
Chris Dumez
Comment 14
2013-03-13 08:32:48 PDT
FYI, The same assertion is easily reproduced in EFL's MiniBrowser if we use CacheModelPrimaryWebBrowser cache model. We currently don't get the assertion with CacheModelDocumentViewer cache model.
Chris Dumez
Comment 15
2013-03-13 12:31:07 PDT
Created
attachment 192962
[details]
Alternative patch This patch fixes the assertion hit for me.
Alexandre Elias
Comment 16
2013-03-13 12:37:17 PDT
Seems reasonable to me (although I'm not a WebKit reviewer). Since this approaches fixes the underlying problem, please also delete the "if (!frame()->view()) return;" statement in FrameView::visibleContentsResized() which was a workaround for the same issue.
Simon Fraser (smfr)
Comment 17
2013-03-13 12:50:49 PDT
Comment on
attachment 192962
[details]
Alternative patch View in context:
https://bugs.webkit.org/attachment.cgi?id=192962&action=review
> Source/WebCore/ChangeLog:11 > + Update RenderView so it retrieves the FrameView from the Document instead > + of storing it as a member upon construction. This makes sure that the > + FrameView returned by the RenderView always matches the one of the > + Document.
But this implies that the RenderView can retrieve a different FrameView at different times, which is totally unexpected. I think this change is just papering over the cracks. We need to understand why the wrong FrameView is retrieved when the assertion happens.
Mikhail Pozdnyakov
Comment 18
2013-03-22 07:31:58 PDT
***
Bug 112921
has been marked as a duplicate of this bug. ***
Mikhail Pozdnyakov
Comment 19
2013-03-22 07:49:04 PDT
(In reply to
comment #17
)
> (From update of
attachment 192962
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=192962&action=review
> > > Source/WebCore/ChangeLog:11 > > + Update RenderView so it retrieves the FrameView from the Document instead > > + of storing it as a member upon construction. This makes sure that the > > + FrameView returned by the RenderView always matches the one of the > > + Document. > > But this implies that the RenderView can retrieve a different FrameView at different times, which is totally unexpected. I think this change is just papering over the cracks. We need to understand why the wrong FrameView is retrieved when the assertion happens.
The wrong frame view is retrieved because FrameView is created several times for the same frame. The frame however always has the same document instance which has the same renderer (RenderView) and RenderView has the same pointer to FrameView (which is out-dated). There are several ways to fix it, and I am not sure which is the best now. Do we really need different FrameView instances for the same frame? Cannot we re-use the existing one instead of re-creating it? And if we do need to re-create FrameView, we probably need to re-create some other objects (document renderer at least because it contains invalid data otherwise). (I was uploading the exactly same patch to
bug#112921
, but noticed that the current bug is already addressing the issue :) ).
Mikhail Pozdnyakov
Comment 20
2013-04-04 07:27:58 PDT
Created
attachment 196476
[details]
another alternative
Simon Fraser (smfr)
Comment 21
2013-04-04 08:36:35 PDT
Comment on
attachment 196476
[details]
another alternative This is wrong too; you're throwing away a layout that should happen at some point. I think the real issue is the call to setUseFixedLayout() on the page that's going into the page cache. Why does that happen?
Simon Fraser (smfr)
Comment 22
2013-04-04 15:17:18 PDT
So
http://trac.webkit.org/changeset/141450
caused setUseFixedLayout() to trigger layout, which seems to be the cause of this bug.
Alexandre Elias
Comment 23
2013-04-04 15:28:27 PDT
(In reply to
comment #22
)
> So
http://trac.webkit.org/changeset/141450
caused setUseFixedLayout() to trigger layout, which seems to be the cause of this bug.
Yes, in #3 I suggested deleting the call in setUseFixedLayout(). This seems reasonable assuming setUseFixedLayout isn't used in a dynamic manner (which no one does to my knowledge).
Mikhail Pozdnyakov
Comment 24
2013-04-05 06:55:53 PDT
(In reply to
comment #23
)
> (In reply to
comment #22
) > > So
http://trac.webkit.org/changeset/141450
caused setUseFixedLayout() to trigger layout, which seems to be the cause of this bug. > > Yes, in #3 I suggested deleting the call in setUseFixedLayout(). This seems reasonable assuming setUseFixedLayout isn't used in a dynamic manner (which no one does to my knowledge).
Unfortunately setUseFixedLayout is used in dynamic manner in WK2 (pls. see void WebPage::setUseFixedLayout(bool fixed) from ./Source/WebKit2/WebProcess/WebPage/WebPage.cpp )
Mikhail Pozdnyakov
Comment 25
2013-04-05 07:07:20 PDT
(In reply to
comment #23
)
> (In reply to
comment #22
) > > So
http://trac.webkit.org/changeset/141450
caused setUseFixedLayout() to trigger layout, which seems to be the cause of this bug. > > Yes, in #3 I suggested deleting the call in setUseFixedLayout(). This seems reasonable assuming setUseFixedLayout isn't used in a dynamic manner (which no one does to my knowledge).
The real problem is that frame's document is not updated by the time re-layout is triggered. Checking document for being in cache before re-layout seems to be an appropriate workaround (for me at least :) ). The ideal solution would be changing frame loader logic so that the view is re-created after the appropriate document had been set, but this looks like a quite significant change of the commonly used (and very complex!) code with a huge risk of various regressions.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug