RESOLVED FIXED 148538
Web Inspector: InspectorController should support multiple frontend channels
https://bugs.webkit.org/show_bug.cgi?id=148538
Summary Web Inspector: InspectorController should support multiple frontend channels
Blaze Burg
Reported 2015-08-27 14:02:09 PDT
First step.
Attachments
Proposed Fix (77.79 KB, patch)
2015-08-28 16:02 PDT, Blaze Burg
no flags
Proposed Fix (EWS) (78.52 KB, patch)
2015-08-28 19:48 PDT, Blaze Burg
no flags
Proposed Fix (EWS) (79.06 KB, patch)
2015-08-28 21:48 PDT, Blaze Burg
no flags
Proposed Fix (for EWS) (79.13 KB, patch)
2015-09-03 15:31 PDT, Blaze Burg
no flags
Proposed Fix (for Win EWS) (81.72 KB, patch)
2015-09-03 16:12 PDT, Blaze Burg
no flags
Proposed Fix (for Win EWS) (81.74 KB, patch)
2015-09-03 17:13 PDT, Blaze Burg
no flags
Proposed Fix (Fix Crash) (81.90 KB, patch)
2015-09-04 11:41 PDT, Blaze Burg
no flags
Radar WebKit Bug Importer
Comment 1 2015-08-27 14:03:02 PDT
Blaze Burg
Comment 2 2015-08-28 16:02:31 PDT
Created attachment 260191 [details] Proposed Fix Here we go.. expecting a few rounds with EWS.
Joseph Pecoraro
Comment 3 2015-08-28 16:50:16 PDT
Comment on attachment 260191 [details] Proposed Fix View in context: https://bugs.webkit.org/attachment.cgi?id=260191&action=review Leaving the review flag for my questions about first frontend connection, last frontend disconnection. > Source/JavaScriptCore/CMakeLists.txt:326 > inspector/InspectorAgentRegistry.cpp > + inspector/InspectorFrontendRouter.cpp > inspector/InspectorBackendDispatcher.cpp Nit: `sort` order. > Source/JavaScriptCore/inspector/InspectorFrontendRouter.h:40 > + bool hasFrontends() const { return m_connections.size() > 0; } Would !Vector::isEmpty be clearer? > Source/JavaScriptCore/inspector/InspectorFrontendRouter.h:55 > + Vector<FrontendChannel*, 2> m_connections; Nice use of size hint! > Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:116 > + m_agents.didCreateFrontendAndBackend(frontendChannel, &m_backendDispatcher.get()); Is the plan that this should happen when adding the first frontend? > Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:130 > + m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed); Is the plan that this should happen when removing the last frontend? > Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:-154 > - if (!m_frontendChannel) > - return; I think the equivalent of this would be: if (!m_frontendRouter.hasFrontends()) return; I'm not quite sure of the consequences here. > Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:276 > - if (m_frontendChannel) > - agent->didCreateFrontendAndBackend(m_frontendChannel, m_backendDispatcher.get()); > + agent->didCreateFrontendAndBackend(m_frontendRouter->leakChannel(), &m_backendDispatcher.get()); > > m_agents.appendExtraAgent(WTF::move(agent)); > > - if (m_frontendChannel) > - m_inspectorAgent->activateExtraDomain(domainName); > + m_inspectorAgent->activateExtraDomain(domainName); Same here. The consequences here seem to just be that you might be doing work in an agent that gets repeated when connectFrontend happens. > Source/WebCore/WebCore.vcxproj/WebCore.vcxproj:20398 > <ClInclude Include="..\ForwardingHeaders\inspector\InspectorFrontendChannel.h" /> > + <ClInclude Include="..\ForwardingHeaders\inspector\InspectorFrontendRouter.h" /> > <ClInclude Include="..\ForwardingHeaders\inspector\InspectorBackendDispatchers.h" /> > <ClInclude Include="..\ForwardingHeaders\inspector\InspectorFrontendDispatchers.h" /> You could correct the sort order while you are here! > Source/WebCore/inspector/InspectorController.cpp:266 > #if ENABLE(REMOTE_INSPECTOR) > - if (!hasRemoteFrontend()) > + if (!m_frontendRouter->hasRemoteFrontend() && didHaveRemoteFrontend) > m_page.remoteInspectorInformationDidChange(); > #endif The purpose of this here is to inform any remote debuggers if this debuggable has a debugger or not. So I think this may have been flawed originally, and it probably should be the same as first/last disconnect conditions. Or for now: if (m_frontendRouter->hasFrontends() && didHaveFrontends()) > Source/WebCore/testing/Internals.cpp:1736 > - bool isAutomaticInspection = false; > m_frontendChannel = std::make_unique<InspectorFrontendChannelDummy>(frontendPage); > - page->inspectorController().connectFrontend(m_frontendChannel.get(), isAutomaticInspection); > + page->inspectorController().connectFrontend(m_frontendChannel.get()); Arg, I hate default parameters. It is easy to make mistakes. But this seems reasonable =)
Blaze Burg
Comment 4 2015-08-28 19:48:15 PDT
Created attachment 260204 [details] Proposed Fix (EWS)
Blaze Burg
Comment 5 2015-08-28 19:56:18 PDT
Comment on attachment 260191 [details] Proposed Fix View in context: https://bugs.webkit.org/attachment.cgi?id=260191&action=review >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:116 >> + m_agents.didCreateFrontendAndBackend(frontendChannel, &m_backendDispatcher.get()); > > Is the plan that this should happen when adding the first frontend? Correct. I tried doing that earlier, but was hitting other issues so I reverted it to help isolate the problem. I will try altering the condition to what you said again, now that everything else is working. >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:130 >> + m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed); > > Is the plan that this should happen when removing the last frontend? Yup, see above. >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:-154 >> - return; > > I think the equivalent of this would be: > > if (!m_frontendRouter.hasFrontends()) > return; > > I'm not quite sure of the consequences here. Is this code related to automatic inspection and auto-resuming? Will investigate. >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:276 >> + m_inspectorAgent->activateExtraDomain(domainName); > > Same here. The consequences here seem to just be that you might be doing work in an agent that gets repeated when connectFrontend happens. How will we know to activate the domain once a frontend connects? Or are these always done together? >> Source/WebCore/inspector/InspectorController.cpp:266 >> #endif > > The purpose of this here is to inform any remote debuggers if this debuggable has a debugger or not. So I think this may have been flawed originally, and it probably should be the same as first/last disconnect conditions. Or for now: > > if (m_frontendRouter->hasFrontends() && didHaveFrontends()) yeah, this condition will change once we want to allow multiple remotes to actually connect. But for now, when should it notify: when a frontend has become detached or when it has become attached? >> Source/WebCore/testing/Internals.cpp:1736 >> + page->inspectorController().connectFrontend(m_frontendChannel.get()); > > Arg, I hate default parameters. It is easy to make mistakes. But this seems reasonable =) It is used so infrequently I thought it was appropriate here.
Blaze Burg
Comment 6 2015-08-28 21:48:06 PDT
Created attachment 260214 [details] Proposed Fix (EWS)
Joseph Pecoraro
Comment 7 2015-08-29 01:15:34 PDT
(In reply to comment #5) > Comment on attachment 260191 [details] > Proposed Fix > > View in context: > https://bugs.webkit.org/attachment.cgi?id=260191&action=review > > >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:116 > >> + m_agents.didCreateFrontendAndBackend(frontendChannel, &m_backendDispatcher.get()); > > > > Is the plan that this should happen when adding the first frontend? > > Correct. I tried doing that earlier, but was hitting other issues so I > reverted it to help isolate the problem. I will try altering the condition > to what you said again, now that everything else is working. > > >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:130 > >> + m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed); > > > > Is the plan that this should happen when removing the last frontend? > > Yup, see above. > > >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:-154 > >> - return; > > > > I think the equivalent of this would be: > > > > if (!m_frontendRouter.hasFrontends()) > > return; > > > > I'm not quite sure of the consequences here. > > Is this code related to automatic inspection and auto-resuming? Will > investigate. Yes, it is. Ping me on IRC if needed and I can show you how to test this / explain how it works. > >> Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:276 > >> + m_inspectorAgent->activateExtraDomain(domainName); > > > > Same here. The consequences here seem to just be that you might be doing work in an agent that gets repeated when connectFrontend happens. > > How will we know to activate the domain once a frontend connects? Or are > these always done together? The normal path is inside JSGlobalObjectInspectorController::connectFrontend (line 123). When a frontend connects we tell it about all the extra domains: m_inspectorAgent->activateExtraDomains(m_agents.extraDomains()); This path here (line 276) is handling when an extra domain is activated and a frontend is already connected, it does the normal agent setup and informs the frontend about this new extra domain. > >> Source/WebCore/inspector/InspectorController.cpp:266 > >> #endif > > > > The purpose of this here is to inform any remote debuggers if this debuggable has a debugger or not. So I think this may have been flawed originally, and it probably should be the same as first/last disconnect conditions. Or for now: > > > > if (m_frontendRouter->hasFrontends() && didHaveFrontends()) > > yeah, this condition will change once we want to allow multiple remotes to > actually connect. But for now, when should it notify: when a frontend has > become detached or when it has become attached? Given how uncommon a frontend connecting/disconnecting is, and how likely it is in practice to actually change some information about the remote debuggable it wouldn't be unreasonable to just always do it when a frontend connects/disconnects.
Blaze Burg
Comment 8 2015-08-29 09:02:57 PDT
The new patch addresses these comments, except the vcxproj reorderings. I hope we nuke those files soon anyway.
Joseph Pecoraro
Comment 9 2015-09-02 18:24:37 PDT
Comment on attachment 260214 [details] Proposed Fix (EWS) View in context: https://bugs.webkit.org/attachment.cgi?id=260214&action=review r=me. I think it might be nicer for clarity to have distinct methods for the code that gets run in the distinct cases. Controller::connectFrontend Controller::disconnectFrontend Controller::firstFrontendConnected (setup?) Controller::lastFrontendDisconnected (teardown?) But it may just be diff ugliness that makes it harder to follow this. > Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:-154 > - if (!m_frontendChannel) > - return; I still think this can be if (!hasFrontends). > Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:-266 > - if (m_frontendChannel) > - agent->didCreateFrontendAndBackend(m_frontendChannel, m_backendDispatcher.get()); Likewise. if (hasFrontend) > Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp:-271 > - if (m_frontendChannel) > - m_inspectorAgent->activateExtraDomain(domainName); Likewise. if (hasFrontend) > Source/WebCore/inspector/InspectorController.cpp:272 > #if ENABLE(REMOTE_INSPECTOR) > - if (!hasRemoteFrontend()) > + if (!m_frontendRouter->hasFrontends() && didHaveRemoteFrontend) > m_page.remoteInspectorInformationDidChange(); > +#else > + UNUSED_PARAM(didHaveRemoteFrontend); > #endif > +} Lets simplify and just always call m_page.remoteInspectorInformationDidChange if we are removing the last frontend.
Blaze Burg
Comment 10 2015-09-03 15:31:13 PDT
Created attachment 260530 [details] Proposed Fix (for EWS)
Blaze Burg
Comment 11 2015-09-03 16:12:10 PDT
Created attachment 260534 [details] Proposed Fix (for Win EWS)
Blaze Burg
Comment 12 2015-09-03 17:13:31 PDT
Created attachment 260541 [details] Proposed Fix (for Win EWS)
WebKit Commit Bot
Comment 13 2015-09-03 20:58:50 PDT
Comment on attachment 260541 [details] Proposed Fix (for Win EWS) Clearing flags on attachment: 260541 Committed r189338: <http://trac.webkit.org/changeset/189338>
WebKit Commit Bot
Comment 14 2015-09-03 20:58:55 PDT
All reviewed patches have been landed. Closing bug.
WebKit Commit Bot
Comment 15 2015-09-03 21:52:09 PDT
Re-opened since this is blocked by bug 148785
Joseph Pecoraro
Comment 16 2015-09-03 21:55:48 PDT
Bots are seeing ASSERTs: ASSERTION FAILED: m_frontendRouter->hasFrontends() /Volumes/Data/slave/yosemite-debug/build/Source/WebCore/inspector/WorkerInspectorController.cpp(130) : void WebCore::WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason) 1 0x114fb7190 WTFCrash 2 0x118b6c8eb WebCore::WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason) 3 0x118b6c627 WebCore::WorkerInspectorController::~WorkerInspectorController() 4 0x118b6caa5 WebCore::WorkerInspectorController::~WorkerInspectorController() 5 0x118b6cac9 WebCore::WorkerInspectorController::~WorkerInspectorController() 6 0x118b61844 WebCore::WorkerGlobalScope::~WorkerGlobalScope() 7 0x116e6e825 WebCore::DedicatedWorkerGlobalScope::~DedicatedWorkerGlobalScope() 8 0x116e6e845 WebCore::DedicatedWorkerGlobalScope::~DedicatedWorkerGlobalScope() 9 0x116e6e899 WebCore::DedicatedWorkerGlobalScope::~DedicatedWorkerGlobalScope() 10 0x116e70103 WTF::RefCounted<WebCore::WorkerGlobalScope>::deref() 11 0x117dc0f11 void WTF::derefIfNotNull<WebCore::WorkerGlobalScope>(WebCore::WorkerGlobalScope*) 12 0x118b91757 WTF::RefPtr<WebCore::WorkerGlobalScope>::operator=(std::nullptr_t) 13 0x118b8dc10 WebCore::WorkerThread::workerThread() 14 0x118b8d6e5 WebCore::WorkerThread::workerThreadStart(void*) 15 0x11501fd89 WTF::createThread(void (*)(void*), void*, char const*)::$_0::operator()() const 16 0x11501fd5c std::__1::__function::__func<WTF::createThread(void (*)(void*), void*, char const*)::$_0, std::__1::allocator<WTF::createThread(void (*)(void*), void*, char const*)::$_0>, void ()>::operator()() 17 0x114aa4e2a std::__1::function<void ()>::operator()() const 18 0x11501ebae WTF::threadEntryPoint(void*) 19 0x115020321 WTF::wtfThreadEntryPoint(void*) 20 0x7fff82a6a05a _pthread_body 21 0x7fff82a69fd7 _pthread_body 22 0x7fff82a673ed thread_start
Blaze Burg
Comment 17 2015-09-04 11:41:14 PDT
Created attachment 260605 [details] Proposed Fix (Fix Crash) Turns out we were unconditionally disconnecting worker controller's frontend channel, when this work was already being done when the workers were spun down.
WebKit Commit Bot
Comment 18 2015-09-04 13:00:30 PDT
Comment on attachment 260605 [details] Proposed Fix (Fix Crash) Clearing flags on attachment: 260605 Committed r189375: <http://trac.webkit.org/changeset/189375>
WebKit Commit Bot
Comment 19 2015-09-04 13:00:34 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.