Bug 53878

Summary: Assertion failure in DrawingAreaImpl::resumePainting after window.open or when opening Web Inspector
Product: WebKit Reporter: Adam Roben (:aroben) <aroben>
Component: Layout and RenderingAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: andersca, sam
Priority: P2 Keywords: InRadar, PlatformOnly
Version: 528+ (Nightly build)   
Hardware: PC   
OS: Windows XP   
Bug Depends on:    
Bug Blocks: 53805    
Attachments:
Description Flags
Hide the ugly details of WebView::m_window initialization from WebPageProxy, and make it less ugly andersca: review+

Description Adam Roben (:aroben) 2011-02-06 08:36:54 PST
To reproduce:

1. Set WEBKIT2_USE_NEW_DRAWING_AREA=1 and launch your WebKit2 browser
2. Right-click on the page and choose Inspect Element

You'll hit an assertion in DrawingAreaImpl::resumePainting:

    ASSERT(m_isPaintingSuspended);

Here's the backtrace:

>	WebKit.dll!WebKit::DrawingAreaImpl::resumePainting()  Line 222 + 0x2c bytes	C++
 	WebKit.dll!CoreIPC::callMemberFunction<WebKit::DrawingArea,void (__thiscall WebKit::DrawingArea::*)(void)>(const CoreIPC::Arguments0 & __formal={...}, WebKit::DrawingArea * object=0x07504d38, void (void)* function=0x1000f420)  Line 13 + 0xb bytes	C++
 	WebKit.dll!CoreIPC::handleMessage<Messages::DrawingArea::ResumePainting,WebKit::DrawingArea,void (__thiscall WebKit::DrawingArea::*)(void)>(CoreIPC::ArgumentDecoder * argumentDecoder=0x070fada8, WebKit::DrawingArea * object=0x07504d38, void (void)* function=0x1000f420)  Line 227 + 0x15 bytes	C++
 	WebKit.dll!WebKit::DrawingArea::didReceiveDrawingAreaMessage(CoreIPC::Connection * __formal=0x0238e208, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x070fada8)  Line 49 + 0x23 bytes	C++
 	WebKit.dll!WebKit::WebPage::didReceiveMessage(CoreIPC::Connection * connection=0x0238e208, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x070fada8)  Line 1662	C++
 	WebKit.dll!WebKit::WebProcess::didReceiveMessage(CoreIPC::Connection * connection=0x0238e208, CoreIPC::MessageID messageID={...}, CoreIPC::ArgumentDecoder * arguments=0x070fada8)  Line 537	C++
 	WebKit.dll!CoreIPC::Connection::dispatchMessages()  Line 441 + 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=0x00040bec, unsigned int message=1025, unsigned int wParam=37276896, long lParam=0)  Line 57	C++
 	WebKit.dll!RunLoop::RunLoopWndProc(HWND__ * hWnd=0x00040bec, unsigned int message=1025, unsigned int wParam=37276896, 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 44 + 0x18 bytes	C++
 	WebKit2WebProcess.exe!__tmainCRTStartup()  Line 589 + 0x1c bytes	C
 	kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes
Comment 1 Adam Roben (:aroben) 2011-02-07 09:12:54 PST
It looks like the sequence of events is essentially this:

Web process:
1) WebInspector::createInspectorPage is called, which sends a synchronous WebInspectorProxy::CreateInspectorPage message to the UI process

UI process:
2) WebInspectorProxy::createInspectorPage is called to handle the message, which ends up creating a new WebView for the page
3) WebView::WebView creates a new HWND, then calls ::ShowWindow(m_window, SW_SHOW) on it
4) The WebView receives a WM_SHOWWINDOW message, which results in a DrawingArea::ResumePainting message being sent to the web process
5) WebInspectorProxy::createInspectorPage calls WebPageProxy::creationParameters to get the parameters to send back to the web process. Since the WebView has already been shown at this point, parameters.isVisible is set to true.
5) WebInspectorProxy::createInspectorPage returns, sending the parameters back to the web process

Web process:
6) WebInspectorProxy::createInspectorPage receives the synchronous message reply it's been waiting for, and creates a new, already-visible page with the WebPageCreationParameters from the UI process.
7) The new page's DrawingArea is created with painting not suspended, because the page is already visible based on the creation parameters.
8) The web process receives the DrawingArea::ResumePainting from (4), and asserts because painting is not suspended.
Comment 2 Adam Roben (:aroben) 2011-02-07 09:16:30 PST
It looks like WebInspector::createInspectorPage is pretty similar to WebChromeClient::createWindow. And, in fact, window.open hits the same assertion!
Comment 3 Adam Roben (:aroben) 2011-02-07 09:39:31 PST
I'm going to try passing WS_VISIBLE to ::CreateWindowExW instead of using a separate ::ShowWindow call.
Comment 4 Adam Roben (:aroben) 2011-02-07 10:41:28 PST
(In reply to comment #3)
> I'm going to try passing WS_VISIBLE to ::CreateWindowExW instead of using a separate ::ShowWindow call.

That fixes the inspector, but not window.open.
Comment 5 Adam Roben (:aroben) 2011-02-09 07:23:37 PST
<rdar://problem/8977306>
Comment 6 Adam Roben (:aroben) 2011-02-09 07:41:12 PST
Created attachment 81813 [details]
Hide the ugly details of WebView::m_window initialization from WebPageProxy, and make it less ugly
Comment 7 Adam Roben (:aroben) 2011-02-09 07:45:47 PST
Committed r78054: <http://trac.webkit.org/changeset/78054>