credit: Marty + ASAN + ClusterFuzz http://code.google.com/p/chromium/issues/detail?id=100958 Bot CLUSTER_FUZZ_331 on platform LINUX Chromium Revision : 106012 Webkit Revision : 97678 Testcase:: <style> .c17 { position: relative; } .c19::after { display: compact; position: absolute; content: no-close-quote; } .c19:nth-of-type(-n+6) { display: run-in;</style> <script> var nodes = Array(); function boom() { try { nodes[45] = document.createElement('thead'); } catch(e) {} try { nodes[45].setAttribute('class', 'c19'); } catch(e) {} try { document.documentElement.appendChild(nodes[45]); } catch(e) {} try { nodes[46] = document.createElement('b'); } catch(e) {} try { nodes[46].setAttribute('class', 'c19'); } catch(e) {} try { document.documentElement.appendChild(nodes[46]); } catch(e) {} try { nodes[47] = document.createElement('header'); } catch(e) {} try { document.documentElement.appendChild(nodes[47]); } catch(e) {} } window.onload = boom; </script> /mnt/scratch0/chrome/src/out/Release/DumpRenderTree ASAN:SIGILL ================================================================= ==16725== ERROR: AddressSanitizer heap-use-after-free on address 0x7f6cbb283ab0 at pc 0x2527275 bp 0x7fff3223adf0 sp 0x7fff3223ace0 READ of size 1 at 0x7f6cbb283ab0 thread T0 #0 0x2527275 in WebCore::RenderBlock::layoutPositionedObjects(bool) #1 0x251d37d in WebCore::RenderBlock::layoutBlock(bool, int, WebCore::RenderBlock::BlockLayoutPass) #2 0x251afe9 in WebCore::RenderBlock::layout() #3 0x27de57b in WebCore::RenderView::layout() #4 0x2045cab in WebCore::FrameView::layout(bool) #5 0x2050277 in WebCore::FrameView::visibleContentsResized() #6 0x16f7d77 in WebCore::ScrollView::updateScrollbars(WebCore::IntSize const&) #7 0x16fa7e4 in WebCore::ScrollView::setContentsSize(WebCore::IntSize const&) #8 0x2041e3b in WebCore::FrameView::setContentsSize(WebCore::IntSize const&) #9 0x2042291 in WebCore::FrameView::adjustViewSize() #10 0x2045e2f in WebCore::FrameView::layout(bool) #11 0x12d2168 in WebCore::Document::implicitClose() #12 0x1ee65dc in WebCore::FrameLoader::checkCompleted() #13 0x1ee28c8 in WebCore::FrameLoader::finishedParsing() #14 0x12f073e in WebCore::Document::finishedParsing() #15 0x15b9b4e in WebCore::HTMLDocumentParser::prepareToStopParsing() #16 0x1ec4444 in WebCore::DocumentWriter::endIfNotLoadingMainResource() #17 0x1f030f9 in WebCore::FrameLoader::finishedLoading() #18 0x1f28034 in WebCore::MainResourceLoader::didFinishLoading(double) #19 0x338c097 in webkit_glue::WebURLLoaderImpl::Context::OnCompletedRequest(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&) #20 0x34c3c03 in (anonymous namespace)::RequestProxy::NotifyCompletedRequest(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&) webkit/tools/test_shell/simple_resource_loader_bridge.cc:0 #21 0x34c405e in base::internal::Invoker4<false, base::internal::InvokerStorage4<void ((anonymous namespace)::RequestProxy::*)(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&), (anonymous namespace)::RequestProxy*, net::URLRequestStatus, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, base::Time>, void ((anonymous namespace)::RequestProxy::*)(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&)>::DoInvoke(base::internal::InvokerStorageBase*) webkit/tools/test_shell/simple_resource_loader_bridge.cc:0 #22 0x866067 in MessageLoop::RunTask(MessageLoop::PendingTask const&) #23 0x866819 in MessageLoop::DeferOrRunPendingTask(MessageLoop::PendingTask const&) #24 0x867cd8 in MessageLoop::DoWork() #25 0x8aef0f in (anonymous namespace)::WorkSourceDispatch(_GSource*, int (*)(void*), void*) base/message_pump_glib.cc:0 #26 0x7f6cc34298c2 in g_main_dispatch /build/buildd/glib2.0-2.24.1/glib/gmain.c:1960 #27 0x7f6cc342d748 in g_main_context_iterate /build/buildd/glib2.0-2.24.1/glib/gmain.c:2591 #28 0x7f6cc342d8fc in IA__g_main_context_iteration /build/buildd/glib2.0-2.24.1/glib/gmain.c:2654 #29 0x8b1361 in base::MessagePumpGtk::RunOnce(_GMainContext*, bool) #30 0x8afa6d in base::MessagePumpGlib::RunWithDispatcher(base::MessagePump::Delegate*, base::MessagePumpDispatcher*) #31 0x864ba9 in MessageLoop::RunInternal() #32 0x863ad9 in MessageLoop::Run() #33 0x48d2f5 in TestShell::waitTestFinished() #34 0x4847a2 in TestShell::runFileTest(TestParams const&) #35 0x434dda in runTest(TestShell&, TestParams&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) third_party/WebKit/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp:0 #36 0x433ab7 in main #37 0x7f6cbf7c7c4d in __libc_start_main /build/buildd/eglibc-2.11.1/csu/libc-start.c:258 #38 0x419499 in _start 0x7f6cbb283ab0 is located 48 bytes inside of 184-byte region [0x7f6cbb283a80,0x7f6cbb283b38) freed by thread T0 here: #1 0x27328ef in WebCore::RenderObjectChildList::destroyLeftoverChildren() #2 0x250e3e0 in WebCore::RenderBlock::willBeDestroyed() #3 0x272cd32 in WebCore::RenderObject::destroy() #4 0x252d915 in WebCore::RenderBlock::handleRunInChild(WebCore::RenderBox*) #5 0x25242f6 in WebCore::RenderBlock::layoutBlockChildren(bool, int&) #6 0x251c59b in WebCore::RenderBlock::layoutBlock(bool, int, WebCore::RenderBlock::BlockLayoutPass) #7 0x251afe9 in WebCore::RenderBlock::layout() #8 0x2537e94 in WebCore::RenderBlock::layoutBlockChild(WebCore::RenderBox*, WebCore::RenderBlock::MarginInfo&, int&, int&) #9 0x252431a in WebCore::RenderBlock::layoutBlockChildren(bool, int&) #10 0x251c59b in WebCore::RenderBlock::layoutBlock(bool, int, WebCore::RenderBlock::BlockLayoutPass) #11 0x251afe9 in WebCore::RenderBlock::layout() #12 0x27de57b in WebCore::RenderView::layout() #13 0x2045cab in WebCore::FrameView::layout(bool) #14 0x2050277 in WebCore::FrameView::visibleContentsResized() #15 0x16f7d77 in WebCore::ScrollView::updateScrollbars(WebCore::IntSize const&) #16 0x16fa7e4 in WebCore::ScrollView::setContentsSize(WebCore::IntSize const&) #17 0x2041e3b in WebCore::FrameView::setContentsSize(WebCore::IntSize const&) #18 0x2042291 in WebCore::FrameView::adjustViewSize() #19 0x2045e2f in WebCore::FrameView::layout(bool) #20 0x12d2168 in WebCore::Document::implicitClose() #21 0x1ee65dc in WebCore::FrameLoader::checkCompleted() #22 0x1ee28c8 in WebCore::FrameLoader::finishedParsing() #23 0x12f073e in WebCore::Document::finishedParsing() #24 0x15b9b4e in WebCore::HTMLDocumentParser::prepareToStopParsing() #25 0x1ec4444 in WebCore::DocumentWriter::endIfNotLoadingMainResource() #26 0x1f030f9 in WebCore::FrameLoader::finishedLoading() #27 0x1f28034 in WebCore::MainResourceLoader::didFinishLoading(double) #28 0x338c097 in webkit_glue::WebURLLoaderImpl::Context::OnCompletedRequest(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&) #29 0x34c3c03 in (anonymous namespace)::RequestProxy::NotifyCompletedRequest(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&) webkit/tools/test_shell/simple_resource_loader_bridge.cc:0 previously allocated by thread T0 here: #1 0x2714f6d in WebCore::RenderObject::createObject(WebCore::Node*, WebCore::RenderStyle*) #2 0x273769b in WebCore::RenderObjectChildList::updateBeforeAfterContent(WebCore::RenderObject*, WebCore::PseudoId, WebCore::RenderObject const*) #3 0x25103ba in WebCore::RenderBlock::styleDidChange(WebCore::StyleDifference, WebCore::RenderStyle const*) #4 0x272733e in WebCore::RenderObject::setStyle(WTF::PassRefPtr<WebCore::RenderStyle>) #5 0x272665b in WebCore::RenderObject::setAnimatableStyle(WTF::PassRefPtr<WebCore::RenderStyle>) #6 0x1389b7d in WebCore::NodeRendererFactory::createRenderer() #7 0x138a35e in WebCore::NodeRendererFactory::createRendererIfNeeded() #8 0x13693b6 in WebCore::Node::createRendererIfNeeded() #9 0x132dfd5 in WebCore::Element::attach() #10 0x132ff5c in WebCore::Element::recalcStyle(WebCore::Node::StyleChange) #11 0x1330c6c in WebCore::Element::recalcStyle(WebCore::Node::StyleChange) #12 0x12cf572 in WebCore::Document::recalcStyle(WebCore::Node::StyleChange) #13 0x12d281f in WebCore::Document::updateStyleIfNeeded() #14 0x12d202f in WebCore::Document::implicitClose() #15 0x1ee65dc in WebCore::FrameLoader::checkCompleted() #16 0x1ee28c8 in WebCore::FrameLoader::finishedParsing() #17 0x12f073e in WebCore::Document::finishedParsing() #18 0x15b9b4e in WebCore::HTMLDocumentParser::prepareToStopParsing() #19 0x1ec4444 in WebCore::DocumentWriter::endIfNotLoadingMainResource() #20 0x1f030f9 in WebCore::FrameLoader::finishedLoading() #21 0x1f28034 in WebCore::MainResourceLoader::didFinishLoading(double) #22 0x338c097 in webkit_glue::WebURLLoaderImpl::Context::OnCompletedRequest(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&) #23 0x34c3c03 in (anonymous namespace)::RequestProxy::NotifyCompletedRequest(net::URLRequestStatus const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, base::Time const&) webkit/tools/test_shell/simple_resource_loader_bridge.cc:0 ==16725== ABORTING Shadow byte and word: 0x1fed97650756: fd 0x1fed97650750: fd fd fd fd fd fd fd fd More shadow bytes: 0x1fed97650730: 00 00 00 00 00 00 00 00 0x1fed97650738: 00 00 00 00 00 00 00 00 0x1fed97650740: fa fa fa fa fa fa fa fa 0x1fed97650748: fa fa fa fa fa fa fa fa =>0x1fed97650750: fd fd fd fd fd fd fd fd 0x1fed97650758: fd fd fd fd fd fd fd fd 0x1fed97650760: fd fd fd fd fd fd fd fd 0x1fed97650768: fd fd fd fd fd fd fd fd 0x1fed97650770: fa fa fa fa fa fa fa fa base::debug::StackTrace::StackTrace() [0x8c5296] base::(anonymous namespace)::StackDumpSignalHandler() [0x891e2f] 0x7f6cbf7dcaf0 0x7f6cbf7dca75 0x7f6cbf7e05c0 asan_report_error() [0x4873140] 0x7f6cc06ce8f0 WebCore::RenderBlock::layoutPositionedObjects() [0x2527275] WebCore::RenderBlock::layoutBlock() [0x251d37d] WebCore::RenderBlock::layout() [0x251afe9] WebCore::RenderView::layout() [0x27de57b] WebCore::FrameView::layout() [0x2045cab] WebCore::FrameView::visibleContentsResized() [0x2050277] WebCore::ScrollView::updateScrollbars() [0x16f7d77] WebCore::ScrollView::setContentsSize() [0x16fa7e4] WebCore::FrameView::setContentsSize() [0x2041e3b] WebCore::FrameView::adjustViewSize() [0x2042291] WebCore::FrameView::layout() [0x2045e2f] WebCore::Document::implicitClose() [0x12d2168] WebCore::FrameLoader::checkCompleted() [0x1ee65dc] WebCore::FrameLoader::finishedParsing() [0x1ee28c8] WebCore::Document::finishedParsing() [0x12f073e] WebCore::HTMLDocumentParser::prepareToStopParsing() [0x15b9b4e] WebCore::DocumentWriter::endIfNotLoadingMainResource() [0x1ec4444] WebCore::FrameLoader::finishedLoading() [0x1f030f9] WebCore::MainResourceLoader::didFinishLoading() [0x1f28034] webkit_glue::WebURLLoaderImpl::Context::OnCompletedRequest() [0x338c097] (anonymous namespace)::RequestProxy::NotifyCompletedRequest() [0x34c3c03] base::internal::Invoker4<>::DoInvoke() [0x34c405e] MessageLoop::RunTask() [0x866067] MessageLoop::DeferOrRunPendingTask() [0x866819] MessageLoop::DoWork() [0x867cd8] (anonymous namespace)::WorkSourceDispatch() [0x8aef0f] 0x7f6cc34298c2 0x7f6cc342d748 0x7f6cc342d8fc base::MessagePumpGtk::RunOnce() [0x8b1361] base::MessagePumpGlib::RunWithDispatcher() [0x8afa6d] MessageLoop::RunInternal() [0x864ba9] MessageLoop::Run() [0x863ad9] TestShell::waitTestFinished() [0x48d2f5] TestShell::runFileTest() [0x4847a2] runTest() [0x434dda] main [0x433ab7] 0x7f6cbf7c7c4d 0x419499
<rdar://problem/10317548>
Reduced testcase:: <style> .testclass::before { position: absolute; content: ""; } .testclass { display: run-in; } </style> <script> function runTest() { test1 = document.createElement('div'); test1.setAttribute('class', 'testclass'); document.documentElement.appendChild(test1); test2 = document.createElement('b'); test2.setAttribute('class', 'testclass'); document.documentElement.appendChild(test2); test3 = document.createElement('div'); document.documentElement.appendChild(test3); } window.onload = runTest; </script>
The run-in is significant. handleRunInChild() removes the run-in block from the render tree before destroying it. So positioned (or possibly floating) children that are getting destroyed are unable to clear themselves from the positioned/floating object list of a higher-level renderer (in the case of absolute positioned generated content, the RenderView). It only happens with generated content because normal content underneath the block run-in is transferred to the inline run-in, rather than being destroyed. This seems like it should be an easy fix, but for reasons I don't yet understand, the obvious solution (leave the renderer on the tree until you delete it) breaks a test. Something gets messed up with RenderLayers.
Discussed with aarya: he is advocating to try to solve the general case: when a node with positioned descendants is removed from the tree, how do we clear those descendants from the positioned object list of its ancestors? AFAICT, this would imply a full subtree traversal whenever we remove a child, because there could be absolute positioned descendants anywhere down there. It looks like we already do a partial subtree traversal looking for floats, but that is somewhat limited because we don't look at (e.g.) floats that are children of non-floating children. We could turn that partial traversal (i.e. markAllDescendantsWithFloatsForLayout()) into a full traversal that looks for both floats and positioned objects, but this might still have performance concerns.
Created attachment 115484 [details] Patch
The patch I just uploaded is a local solution to this specific case, not a general solution. Given that a general solution to the problem I describe in comment 4 seems difficult (to me, anyway), I'm not inclined to write one unless it is clear it is worth it.
Comment on attachment 115484 [details] Patch r=me
Comment on attachment 115484 [details] Patch Clearing flags on attachment: 115484 Committed r100677: <http://trac.webkit.org/changeset/100677>
All reviewed patches have been landed. Closing bug.
*** Bug 72666 has been marked as a duplicate of this bug. ***