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)
Created attachment 7739 [details] test case
Created attachment 7741 [details] Reduced test case (crashes when closing the window)
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.
Created attachment 7743 [details] Don't allow splitting button's inner container ...or you can call it isButton() and reverse the values.
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.
Oops, you are refereing to render tree children here. nm then. JS can't access those.