Bug 8420

Summary: iExploder(#12): Assertion failure in RenderContainer::removeChildNode
Product: WebKit Reporter: Alexey Proskuryakov <ap>
Component: Layout and RenderingAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: bugs-webkit, mitz
Priority: P2 Keywords: HasReduction
Version: 420+   
Hardware: Mac   
OS: OS X 10.4   
Attachments:
Description Flags
test case
none
Reduced test case (crashes when closing the window)
none
Don't allow splitting button's inner container eric: review+

Description Alexey Proskuryakov 2006-04-16 04:04:05 PDT
Steps to reproduce:
1. Open the attached file in a debug build of WebKit.
2. Close the weindow.

Result:
=================
ASSERTION FAILED: oldChild->parent() == this (/Users/ap/WebKit/WebCore/rendering/RenderContainer.cpp:163 virtual WebCore::RenderObject* WebCore::RenderContainer::removeChildNode(WebCore::RenderObject*))
=================

Thread 0 Crashed:
0   com.apple.WebCore              	0x0197f094 WebCore::RenderContainer::removeChildNode(WebCore::RenderObject*) + 128 (RenderContainer.cpp:163)
1   com.apple.WebCore              	0x0197f388 WebCore::RenderContainer::removeChild(WebCore::RenderObject*) + 64 (RenderContainer.cpp:214)
2   com.apple.WebCore              	0x0195ca34 WebCore::RenderBlock::removeChild(WebCore::RenderObject*) + 640 (RenderBlock.cpp:320)
3   com.apple.WebCore              	0x0197ad3c WebCore::RenderButton::removeChild(WebCore::RenderObject*) + 148 (render_button.cpp:62)
4   com.apple.WebCore              	0x019b9b74 WebCore::RenderObject::remove() + 156 (RenderObject.cpp:2051)
5   com.apple.WebCore              	0x019b9d5c WebCore::RenderObject::destroy() + 32 (RenderObject.cpp:2067)
6   com.apple.WebCore              	0x01970098 WebCore::RenderBox::destroy() + 88 (RenderBox.cpp:147)
7   com.apple.WebCore              	0x0197ef50 WebCore::RenderContainer::destroy() + 44 (RenderContainer.cpp:58)
8   com.apple.WebCore              	0x01988228 WebCore::RenderFlow::destroy() + 576 (RenderFlow.cpp:225)
9   com.apple.WebCore              	0x0198803c WebCore::RenderFlow::destroy() + 84 (RenderFlow.cpp:182)
10  com.apple.WebCore              	0x01a9cd94 WebCore::Node::detach() + 124 (Node.cpp:699)
11  com.apple.WebCore              	0x018c120c WebCore::ContainerNode::detach() + 112 (ContainerNode.cpp:580)
12  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
13  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
14  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
15  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
16  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
17  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
18  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
19  com.apple.WebCore              	0x018c11e4 WebCore::ContainerNode::detach() + 72 (ContainerNode.cpp:577)
20  com.apple.WebCore              	0x018ba590 WebCore::Document::detach() + 220 (Document.cpp:978)
21  com.apple.WebCore              	0x018a71e0 WebCore::FrameMac::setView(WebCore::FrameView*) + 184 (FrameMac.mm:610)
22  com.apple.WebCore              	0x019dad4c WebCore::Page::~Page [in-charge]() + 84 (Page.cpp:51)
23  com.apple.WebCore              	0x018d53dc -[WebCorePageBridge dealloc] + 64 (WebCorePageBridge.mm:83)
24  com.apple.WebKit               	0x003ab960 -[WebView(WebPrivate) _close] + 224 (WebView.m:556)
Comment 1 Alexey Proskuryakov 2006-04-16 04:04:27 PDT
Created attachment 7739 [details]
test case
Comment 2 mitz 2006-04-16 04:48:10 PDT
Created attachment 7741 [details]
Reduced test case (crashes when closing the window)
Comment 3 mitz 2006-04-16 05:47:37 PDT
The root cause of this bug is that RenderInline::splitFlow() recycles the button's inner anonymous block for the beginning of the split flow and puts the rest in sibling anonymous blocks, whereas the button expects all its children to be in the inner anonymous block it created initially.

I think the inner anonymous block should be maintained as the button's only child, so splitFlow() should avoid recycling it. Since only buttons need this behavior, maybe it's okay to simply check if the anonymous block's parent is a button.
Comment 4 mitz 2006-04-16 07:18:10 PDT
Created attachment 7743 [details]
Don't allow splitting button's inner container

...or you can call it isButton() and reverse the values.
Comment 5 Eric Seidel (no email) 2006-04-16 12:49:31 PDT
Comment on attachment 7743 [details]
Don't allow splitting button's inner container

The patch looks totally sane.  The layout test could possibly have been simpler (using JS to test the number of children for instance).  My only concern is performance, I have no idea how hot this code is.  I'm going to r+ and leave hyatt or darin to complain if I was wrong.
Comment 6 Eric Seidel (no email) 2006-04-16 12:56:05 PDT
Oops, you are refereing to render tree children here.  nm then.  JS can't access those.