Bug 54123

Summary: Assertion failure in BackingStore::BackingStore if new WebPage becomes active before receiving a size
Product: WebKit Reporter: Adam Roben (:aroben) <aroben>
Component: Layout and RenderingAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: andersca
Priority: P2 Keywords: InRadar, PlatformOnly
Version: 528+ (Nightly build)   
Hardware: PC   
OS: Windows XP   
Bug Depends on:    
Bug Blocks: 53805    
Attachments:
Description Flags
Don't invalidate outside of the WebPage's bounds darin: review+

Description Adam Roben (:aroben) 2011-02-09 11:27:14 PST
If a new WebPage becomes active before it receives a size, you'll hit this assertion in BackingStore::BackingStore:

    ASSERT(!m_size.isEmpty());


Continuing past the assertion shows no bad effects, so presumably Release builds are unaffected. Here's the backtrace:

>	WebKit.dll!WebKit::BackingStore::BackingStore(const WebCore::IntSize & size={...}, WebKit::WebPageProxy * webPageProxy=0x09755c90)  Line 49 + 0x2d bytes	C++
 	WebKit.dll!WebKit::BackingStore::create(const WebCore::IntSize & size={...}, WebKit::WebPageProxy * webPageProxy=0x09755c90)  Line 42 + 0x23 bytes	C++
 	WebKit.dll!WebKit::DrawingAreaProxyImpl::incorporateUpdate(const WebKit::UpdateInfo & updateInfo={...})  Line 203 + 0x14 bytes	C++
 	WebKit.dll!WebKit::DrawingAreaProxyImpl::update(unsigned __int64 sequenceNumber=2, const WebKit::UpdateInfo & updateInfo={...})  Line 142	C++
 	WebKit.dll!CoreIPC::callMemberFunction<WebKit::DrawingAreaProxy,void (__thiscall WebKit::DrawingAreaProxy::*)(unsigned __int64,WebKit::UpdateInfo const &),unsigned __int64,WebKit::UpdateInfo>(const CoreIPC::Arguments2<unsigned __int64,WebKit::UpdateInfo> & args={...}, WebKit::DrawingAreaProxy * object=0x0972f508, void (unsigned __int64, const WebKit::UpdateInfo &)* function=0x0382cab3)  Line 25 + 0x19 bytes	C++
 	WebKit.dll!CoreIPC::handleMessage<Messages::DrawingAreaProxy::Update,WebKit::DrawingAreaProxy,void (__thiscall WebKit::DrawingAreaProxy::*)(unsigned __int64,WebKit::UpdateInfo const &)>(CoreIPC::ArgumentDecoder * argumentDecoder=0x0a218f28, WebKit::DrawingAreaProxy * object=0x0972f508, void (unsigned __int64, const WebKit::UpdateInfo &)* function=0x0382cab3)  Line 246 + 0x11 bytes	C++
 	WebKit.dll!WebKit::DrawingAreaProxy::didReceiveDrawingAreaProxyMessage(CoreIPC::Connection * __formal=0x07943920, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x0a218f28)  Line 41 + 0x12 bytes	C++
 	WebKit.dll!WebKit::WebPageProxy::didReceiveMessage(CoreIPC::Connection * connection=0x07943920, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x0a218f28)  Line 1169	C++
 	WebKit.dll!WebKit::WebProcessProxy::didReceiveMessage(CoreIPC::Connection * connection=0x07943920, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x0a218f28)  Line 245	C++
 	WebKit.dll!CoreIPC::Connection::dispatchMessages()  Line 450 + 0x31 bytes	C++
 	WebKit.dll!MemberFunctionWorkItem0<CoreIPC::Connection>::execute()  Line 76 + 0x10 bytes	C++
 	WebKit.dll!RunLoop::performWork()  Line 63 + 0x1a bytes	C++
 	WebKit.dll!RunLoop::wndProc(HWND__ * hWnd=0x00190762, unsigned int message=1025, unsigned int wParam=115649320, long lParam=0)  Line 57	C++
 	WebKit.dll!RunLoop::RunLoopWndProc(HWND__ * hWnd=0x00190762, unsigned int message=1025, unsigned int wParam=115649320, long lParam=0)  Line 39 + 0x18 bytes	C++
Comment 1 Adam Roben (:aroben) 2011-02-09 11:27:24 PST
<rdar://problem/8978383>
Comment 2 Adam Roben (:aroben) 2011-02-09 11:28:10 PST
It looks like we end up scheduling a display in the web process before the WebPage has received a size. The display is being scheduled at this point:

>	WebKit.dll!WebKit::DrawingAreaImpl::scheduleDisplay()  Line 334	C++
 	WebKit.dll!WebKit::DrawingAreaImpl::setNeedsDisplay(const WebCore::IntRect & rect={...})  Line 87	C++
 	WebKit.dll!WebKit::WebChromeClient::invalidateContentsAndWindow(const WebCore::IntRect & rect={...}, bool __formal=false)  Line 362 + 0x21 bytes	C++
 	WebKit.dll!WebCore::Chrome::invalidateContentsAndWindow(const WebCore::IntRect & updateRect={...}, bool immediate=false)  Line 77 + 0x20 bytes	C++
 	WebKit.dll!WebCore::FrameView::invalidateRect(const WebCore::IntRect & rect={...})  Line 316 + 0x2e bytes	C++
 	WebKit.dll!WebCore::FrameView::invalidateScrollbarRect(WebCore::Scrollbar * scrollbar=0x022f8ab8, const WebCore::IntRect & rect={...})  Line 2012 + 0x17 bytes	C++
 	WebKit.dll!WebCore::Scrollbar::invalidateRect(const WebCore::IntRect & rect={...})  Line 453 + 0x1d bytes	C++
 	WebKit.dll!WebCore::Widget::invalidate()  Line 166 + 0x3a bytes	C++
 	WebKit.dll!WebCore::Scrollbar::setEnabled(bool e=false)  Line 432	C++
 	WebKit.dll!WebCore::ScrollView::updateScrollbars(const WebCore::IntSize & desiredOffset={...})  Line 555 + 0x38 bytes	C++
 	WebKit.dll!WebCore::ScrollView::setScrollbarModes(WebCore::ScrollbarMode horizontalMode=ScrollbarAuto, WebCore::ScrollbarMode verticalMode=ScrollbarAlwaysOn, bool horizontalLock=false, bool verticalLock=false)  Line 161	C++
 	WebKit.dll!WebCore::ScrollView::setVerticalScrollbarMode(WebCore::ScrollbarMode mode=ScrollbarAlwaysOn, bool lock=false)  Line 94 + 0x30 bytes	C++
 	WebKit.dll!WebCore::FrameView::layout(bool allowSubtree=true)  Line 859	C++
 	WebKit.dll!WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive()  Line 2311	C++
 	WebKit.dll!WebCore::FocusController::setActive(bool active=true)  Line 409	C++
 	WebKit.dll!WebKit::WebPage::setActive(bool isActive=true)  Line 1061	C++
 	WebKit.dll!CoreIPC::callMemberFunction<WebKit::WebPage,void (__thiscall WebKit::WebPage::*)(bool),bool>(const CoreIPC::Arguments1<bool> & args={...}, WebKit::WebPage * object=0x022fd148, void (bool)* function=0x10005d53)  Line 19 + 0x11 bytes	C++
 	WebKit.dll!CoreIPC::handleMessage<Messages::WebPage::SetActive,WebKit::WebPage,void (__thiscall WebKit::WebPage::*)(bool)>(CoreIPC::ArgumentDecoder * argumentDecoder=0x0231d308, WebKit::WebPage * object=0x022fd148, void (bool)* function=0x10005d53)  Line 246 + 0x15 bytes	C++
 	WebKit.dll!WebKit::WebPage::didReceiveWebPageMessage(CoreIPC::Connection * __formal=0x022be3a0, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x0231d308)  Line 48 + 0x23 bytes	C++
 	WebKit.dll!WebKit::WebPage::didReceiveMessage(CoreIPC::Connection * connection=0x022be3a0, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x0231d308)  Line 1718	C++
 	WebKit.dll!WebKit::WebProcess::didReceiveMessage(CoreIPC::Connection * connection=0x022be3a0, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x0231d308)  Line 539	C++
 	WebKit.dll!CoreIPC::Connection::dispatchMessages()  Line 450 + 0x31 bytes	C++
 	WebKit.dll!MemberFunctionWorkItem0<CoreIPC::Connection>::execute()  Line 76 + 0x10 bytes	C++
 	WebKit.dll!RunLoop::performWork()  Line 63 + 0x1a bytes	C++
 	WebKit.dll!RunLoop::wndProc(HWND__ * hWnd=0x002f0a44, unsigned int message=1025, unsigned int wParam=36335296, long lParam=0)  Line 57	C++
 	WebKit.dll!RunLoop::RunLoopWndProc(HWND__ * hWnd=0x002f0a44, unsigned int message=1025, unsigned int wParam=36335296, long lParam=0)  Line 39 + 0x18 bytes	C++
 	user32.dll!_InternalCallWinProc@20()  + 0x28 bytes	
 	user32.dll!_UserCallWinProcCheckWow@32()  + 0xb7 bytes	
 	user32.dll!_DispatchMessageWorker@8()  + 0xdc bytes	
 	user32.dll!_DispatchMessageW@4()  + 0xf bytes	
 	WebKit.dll!RunLoop::run()  Line 73 + 0xc bytes	C++
 	WebKit.dll!WebKit::WebProcessMain(const WebKit::CommandLine & commandLine={...})  Line 82	C++
 	WebKit.dll!WebKitMain(const WebKit::CommandLine & commandLine={...})  Line 48 + 0x9 bytes	C++
 	WebKit.dll!WebKitMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpstrCmdLine=0x0002114c, int nCmdShow=10)  Line 172 + 0x9 bytes	C++
 	WebKit2WebProcess.exe!wWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpstrCmdLine=0x0002114c, int nCmdShow=10)  Line 66 + 0x18 bytes	C++
 	WebKit2WebProcess.exe!__tmainCRTStartup()  Line 589 + 0x1c bytes	C
 	kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes	

I.e., the WebPage is becoming active, so invalidates its scrollbar, which is non-zero-sized due to this code in Scrollbar::Scrollbar:

    // FIXME: This is ugly and would not be necessary if we fix cross-platform code to actually query for
    // scrollbar thickness and use it when sizing scrollbars (rather than leaving one dimension of the scrollbar
    // alone when sizing).
    int thickness = m_theme->scrollbarThickness(controlSize);
    Widget::setFrameRect(IntRect(0, 0, thickness, thickness));

I think we should not schedule a display at all in this case, since the WebPage is zero-sized.
Comment 3 Adam Roben (:aroben) 2011-02-09 11:30:54 PST
Created attachment 81840 [details]
Don't invalidate outside of the WebPage's bounds
Comment 4 Adam Roben (:aroben) 2011-02-10 04:42:49 PST
Committed r78197: <http://trac.webkit.org/changeset/78197>