Web Inspector: CRASH when debugger closes while paused and remote inspecting a JSContext
authorjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Feb 2014 03:06:46 +0000 (03:06 +0000)
committerjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Feb 2014 03:06:46 +0000 (03:06 +0000)
commit1eeb034f9448e9a9b020c007bc1b9552245bb70d
tree09dfe1b1e46cad183860c55b1e5137a3b59d67cf
parente92cb70b61baf51dc21c727f8396830943219717
Web Inspector: CRASH when debugger closes while paused and remote inspecting a JSContext
https://bugs.webkit.org/show_bug.cgi?id=127757

Reviewed by Timothy Hatcher.

The problem was that the lifetime of the InspectorController and all agents
was tied to the remote inspector session. So, if a remote inspector was
disconnected while in the nested run loop, everything would get torn
down and when execution continued out of the nested runloop we would be
back in the original call stack of destroyed objects.

This patch changes the lifetime of the InspectorController and agents to
the JSGlobalObject. This way the agents are always alive, just the
frontend and backend channels are destroyed and recreated each remote
inspector session. This matches the agent lifetime for WebCore agents.
We can also later take advantage of the agents being alive before
and between inspector debug sessions to stash exception messages to
pass on to a debugger if a debugger is connected later.

* inspector/JSGlobalObjectInspectorController.h:
* inspector/JSGlobalObjectInspectorController.cpp:
(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
Cleaner initialization of agents. Easier to follow.

(Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
Move InjectedScript disconnection only once the global object is destroyed.
This way if a developer has attached once and included an injected script,
we will keep it around with any state it might want to remember until
the global object is destroyed.

(Inspector::JSGlobalObjectInspectorController::globalObjectDestroyed):
Disconnect agents and injected scripts when the global object is destroyed.

* inspector/InjectedScriptManager.cpp:
(Inspector::InjectedScriptManager::disconnect):
Now that the injected script manager is reused between remote
inspector sessions, don't clear the pointer on disconnect calls.
We now only call this once when the global object is getting
destroyed anyways so it doesn't matter. But if we wanted to call
disconnect multiple times, e.g. once per session, we could.

* inspector/ScriptDebugServer.cpp:
(Inspector::ScriptDebugServer::dispatchFunctionToListeners):
If the only listener was removed during the nested runloop, then when
we dispatch an event after the nested runloop the listener list will
be empty. Instead of asserting, just pass by an empty list.

* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::inspectorController):
Tie the inspector controller lifetime to the JSGlobalObject.

* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::~JSGlobalObject):
(JSC::JSGlobalObject::init):
Create the inspector controller, and eagerly signal teardown
in destruction.

* runtime/JSGlobalObjectDebuggable.h:
* runtime/JSGlobalObjectDebuggable.cpp:
(JSC::JSGlobalObjectDebuggable::connect):
(JSC::JSGlobalObjectDebuggable::disconnect):
(JSC::JSGlobalObjectDebuggable::dispatchMessageFromRemoteFrontend):
Simplify by using the inspector controller on JSGlobalObject.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@164151 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/InjectedScriptManager.cpp
Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp
Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.h
Source/JavaScriptCore/inspector/ScriptDebugServer.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.cpp
Source/JavaScriptCore/runtime/JSGlobalObjectDebuggable.h