Changeset 210822 in webkit
- Timestamp:
- Jan 17, 2017 11:24:23 AM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r210821 r210822 1 2017-01-17 Joseph Pecoraro <pecoraro@apple.com> 2 3 Crash when closing tab with debugger paused 4 https://bugs.webkit.org/show_bug.cgi?id=161746 5 <rdar://problem/15607819> 6 7 Reviewed by Brian Burg and Brent Fulgham. 8 9 * page/Page.h: 10 (WebCore::Page::incrementNestedRunLoopCount): 11 (WebCore::Page::decrementNestedRunLoopCount): 12 (WebCore::Page::insideNestedRunLoop): 13 Keep track of whether or not this Page is inside of a nested run loop. 14 Currently the only nested run loop we know about is EventLoop used 15 by Web Inspector when debugging JavaScript. 16 17 (WebCore::Page::whenUnnested): 18 Callback that can be called when we are no longer inside of a nested 19 run loop. 20 21 (WebCore::Page::~Page): 22 Ensure we are not in a known nested run loop when destructing, since 23 that could be unsafe. 24 25 * inspector/PageScriptDebugServer.cpp: 26 (WebCore::PageScriptDebugServer::runEventLoopWhilePausedInternal): 27 Increment and decrement as we go into or leave the nested runloop. 28 29 * inspector/InspectorController.cpp: 30 (WebCore::InspectorController::inspectedPageDestroyed): 31 (WebCore::InspectorController::disconnectAllFrontends): 32 Rework destruction to allow disconnectAllFrontends to happen earlier 33 if necessary. WebKit clients may use this to disconnect remote 34 frontends when closing a Page. 35 1 36 2017-01-16 Filip Pizlo <fpizlo@apple.com> 2 37 -
trunk/Source/WebCore/inspector/InspectorController.cpp
r209683 r210822 204 204 m_injectedScriptManager->disconnect(); 205 205 206 // If the local frontend page was destroyed, close the window.207 if (m_inspectorFrontendClient)208 m_inspectorFrontendClient->closeWindow();209 210 // The frontend should call setInspectorFrontendClient(nullptr) under closeWindow().211 ASSERT(!m_inspectorFrontendClient);212 213 206 // Clean up resources and disconnect local and remote frontends. 214 207 disconnectAllFrontends(); 208 209 // Disconnect the client. 210 m_inspectorClient->inspectedPageDestroyed(); 211 m_inspectorClient = nullptr; 215 212 216 213 m_agents.discardValues(); … … 301 298 void InspectorController::disconnectAllFrontends() 302 299 { 303 // The local frontend client should be disconnected already. 300 // If the local frontend page was destroyed, close the window. 301 if (m_inspectorFrontendClient) 302 m_inspectorFrontendClient->closeWindow(); 303 304 // The frontend should call setInspectorFrontendClient(nullptr) under closeWindow(). 304 305 ASSERT(!m_inspectorFrontendClient); 306 307 if (!m_frontendRouter->hasFrontends()) 308 return; 305 309 306 310 for (unsigned i = 0; i < m_frontendRouter->frontendCount(); ++i) … … 315 319 // Destroy the inspector overlay's page. 316 320 m_overlay->freePage(); 317 318 // Disconnect local WK2 frontend and destroy the client.319 m_inspectorClient->inspectedPageDestroyed();320 m_inspectorClient = nullptr;321 321 322 322 // Disconnect any remaining remote frontends. -
trunk/Source/WebCore/inspector/PageScriptDebugServer.cpp
r210758 r210822 115 115 TimerBase::fireTimersInNestedEventLoop(); 116 116 117 m_page.incrementNestedRunLoopCount(); 118 117 119 EventLoop loop; 118 120 while (!m_doneProcessingDebuggerEvents && !loop.ended()) 119 121 loop.cycle(); 122 123 m_page.decrementNestedRunLoopCount(); 120 124 } 121 125 -
trunk/Source/WebCore/page/Page.cpp
r210774 r210822 201 201 , m_diagnosticLoggingClient(WTFMove(pageConfiguration.diagnosticLoggingClient)) 202 202 , m_webGLStateTracker(WTFMove(pageConfiguration.webGLStateTracker)) 203 , m_subframeCount(0)204 203 , m_openedByDOM(false) 205 204 , m_tabKeyCyclesThroughElements(true) … … 289 288 Page::~Page() 290 289 { 290 ASSERT(!m_nestedRunLoopCount); 291 ASSERT(!m_unnestCallback); 292 291 293 m_validationMessageClient = nullptr; 292 294 m_diagnosticLoggingClient = nullptr; … … 1685 1687 #endif 1686 1688 1689 void Page::incrementNestedRunLoopCount() 1690 { 1691 m_nestedRunLoopCount++; 1692 } 1693 1694 void Page::decrementNestedRunLoopCount() 1695 { 1696 ASSERT(m_nestedRunLoopCount); 1697 if (m_nestedRunLoopCount <= 0) 1698 return; 1699 1700 m_nestedRunLoopCount--; 1701 1702 if (!m_nestedRunLoopCount && m_unnestCallback) { 1703 callOnMainThread([this] { 1704 if (insideNestedRunLoop()) 1705 return; 1706 1707 // This callback may destruct the Page. 1708 if (m_unnestCallback) { 1709 auto callback = m_unnestCallback; 1710 m_unnestCallback = nullptr; 1711 callback(); 1712 } 1713 }); 1714 } 1715 } 1716 1717 void Page::whenUnnested(std::function<void()> callback) 1718 { 1719 ASSERT(!m_unnestCallback); 1720 1721 m_unnestCallback = callback; 1722 } 1723 1687 1724 #if ENABLE(REMOTE_INSPECTOR) 1688 1725 bool Page::remoteInspectionAllowed() const -
trunk/Source/WebCore/page/Page.h
r210774 r210822 193 193 int subframeCount() const { checkSubframeCountConsistency(); return m_subframeCount; } 194 194 195 void incrementNestedRunLoopCount(); 196 void decrementNestedRunLoopCount(); 197 bool insideNestedRunLoop() const { return m_nestedRunLoopCount > 0; } 198 WEBCORE_EXPORT void whenUnnested(std::function<void()>); 199 195 200 #if ENABLE(REMOTE_INSPECTOR) 196 201 WEBCORE_EXPORT bool remoteInspectionAllowed() const; … … 623 628 std::unique_ptr<WebGLStateTracker> m_webGLStateTracker; 624 629 625 int m_subframeCount; 630 int m_nestedRunLoopCount { 0 }; 631 std::function<void()> m_unnestCallback; 632 633 int m_subframeCount { 0 }; 626 634 String m_groupName; 627 635 bool m_openedByDOM; -
trunk/Source/WebKit/mac/ChangeLog
r210797 r210822 1 2017-01-17 Joseph Pecoraro <pecoraro@apple.com> 2 3 Crash when closing tab with debugger paused 4 https://bugs.webkit.org/show_bug.cgi?id=161746 5 <rdar://problem/15607819> 6 7 Reviewed by Brian Burg and Brent Fulgham. 8 9 * WebView/WebView.mm: 10 (WebKit::DeferredPageDestructor::createDeferredPageDestructor): 11 (WebKit::DeferredPageDestructor::DeferredPageDestructor): 12 (WebKit::DeferredPageDestructor::tryDestruction): 13 (-[WebView _close]): 14 Defer destruction of the Page if we are in a nested runloop. 15 1 16 2017-01-16 Joseph Pecoraro <pecoraro@apple.com> 2 17 -
trunk/Source/WebKit/mac/WebView/WebView.mm
r210779 r210822 583 583 } 584 584 585 namespace WebKit { 586 587 class DeferredPageDestructor { 588 public: 589 static void createDeferredPageDestructor(std::unique_ptr<Page> page) 590 { 591 new DeferredPageDestructor(WTFMove(page)); 592 } 593 594 private: 595 DeferredPageDestructor(std::unique_ptr<Page> page) 596 : m_page(WTFMove(page)) 597 { 598 tryDestruction(); 599 } 600 601 void tryDestruction() 602 { 603 if (m_page->insideNestedRunLoop()) { 604 m_page->whenUnnested([this] { tryDestruction(); }); 605 return; 606 } 607 608 m_page = nullptr; 609 delete this; 610 } 611 612 std::unique_ptr<Page> m_page; 613 }; 614 615 } // namespace WebKit 616 585 617 @interface WebView (WebFileInternal) 586 618 #if !PLATFORM(IOS) … … 2149 2181 // See comment in HistoryItem::releaseAllPendingPageCaches() for more information. 2150 2182 Page* page = _private->page; 2151 _private->page = 0;2152 delete page;2183 _private->page = nullptr; 2184 WebKit::DeferredPageDestructor::createDeferredPageDestructor(std::unique_ptr<Page>(page)); 2153 2185 2154 2186 #if !PLATFORM(IOS) -
trunk/Source/WebKit2/ChangeLog
r210797 r210822 1 2017-01-17 Joseph Pecoraro <pecoraro@apple.com> 2 3 Crash when closing tab with debugger paused 4 https://bugs.webkit.org/show_bug.cgi?id=161746 5 <rdar://problem/15607819> 6 7 Reviewed by Brian Burg and Brent Fulgham. 8 9 * WebProcess/WebPage/WebPage.cpp: 10 (WebKit::DeferredPageDestructor::createDeferredPageDestructor): 11 (WebKit::DeferredPageDestructor::DeferredPageDestructor): 12 (WebKit::DeferredPageDestructor::tryDestruction): 13 (WebKit::WebPage::close): 14 Defer destruction of the Page and WebPage if we are in a nested runloop. 15 Also, proactively close all inspector frontends, including remote frontends. 16 17 * WebProcess/WebPage/ios/WebPageIOS.mm: 18 (WebKit::WebPage::handleSyntheticClick): 19 (WebKit::WebPage::completeSyntheticClick): 20 Return early in some cases where a nested run loop may have closed 21 the WebPage on us while handling JavaScript events. 22 1 23 2017-01-16 Joseph Pecoraro <pecoraro@apple.com> 2 24 -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
r210753 r210822 145 145 #include <WebCore/HistoryItem.h> 146 146 #include <WebCore/HitTestResult.h> 147 #include <WebCore/InspectorController.h> 147 148 #include <WebCore/JSDOMWindow.h> 148 149 #include <WebCore/KeyboardEvent.h> … … 280 281 }; 281 282 283 class DeferredPageDestructor { 284 public: 285 static void createDeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage) 286 { 287 new DeferredPageDestructor(WTFMove(page), webPage); 288 } 289 290 private: 291 DeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage) 292 : m_page(WTFMove(page)) 293 , m_webPage(webPage) 294 { 295 tryDestruction(); 296 } 297 298 void tryDestruction() 299 { 300 if (m_page->insideNestedRunLoop()) { 301 m_page->whenUnnested([this] { tryDestruction(); }); 302 return; 303 } 304 305 m_page = nullptr; 306 m_webPage = nullptr; 307 delete this; 308 } 309 310 std::unique_ptr<Page> m_page; 311 RefPtr<WebPage> m_webPage; 312 }; 313 282 314 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage")); 283 315 … … 1028 1060 } 1029 1061 1062 m_page->inspectorController().disconnectAllFrontends(); 1063 1030 1064 #if ENABLE(FULLSCREEN_API) 1031 1065 m_fullScreenManager = nullptr; … … 1085 1119 m_printContext = nullptr; 1086 1120 m_mainFrame->coreFrame()->loader().detachFromParent(); 1087 m_page = nullptr;1088 1121 m_drawingArea = nullptr; 1122 1123 DeferredPageDestructor::createDeferredPageDestructor(WTFMove(m_page), this); 1089 1124 1090 1125 bool isRunningModal = m_isRunningModal; … … 2399 2434 send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled)); 2400 2435 } 2401 2402 2436 #endif 2403 2437 -
trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm
r210687 r210822 536 536 m_pendingSyntheticClickLocation = FloatPoint(); 537 537 538 if (m_isClosed) 539 return; 540 538 541 switch (WKObservedContentChange()) { 539 542 case WKContentVisibilityChange: … … 571 574 RefPtr<Frame> oldFocusedFrame = m_page->focusController().focusedFrame(); 572 575 RefPtr<Element> oldFocusedElement = oldFocusedFrame ? oldFocusedFrame->document()->focusedElement() : nullptr; 573 m_userIsInteracting = true; 576 577 SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true }; 574 578 575 579 bool tapWasHandled = false; 576 580 m_lastInteractionLocation = roundedAdjustedPoint; 581 577 582 tapWasHandled |= mainframe.eventHandler().handleMousePressEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime(), WebCore::ForceAtClick, syntheticClickType)); 583 if (m_isClosed) 584 return; 585 578 586 tapWasHandled |= mainframe.eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MouseReleased, 1, false, false, false, false, currentTime(), WebCore::ForceAtClick, syntheticClickType)); 587 if (m_isClosed) 588 return; 579 589 580 590 RefPtr<Frame> newFocusedFrame = m_page->focusController().focusedFrame(); … … 587 597 if (newFocusedElement && newFocusedElement == oldFocusedElement) 588 598 elementDidFocus(newFocusedElement.get()); 589 590 m_userIsInteracting = false;591 599 592 600 if (!tapWasHandled || !nodeRespondingToClick || !nodeRespondingToClick->isElementNode())
Note: See TracChangeset
for help on using the changeset viewer.