Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksei Koziatinskii <ak239spb@gmail.com>2019-05-07 05:30:44 +0300
committerAleksei Koziatinskii <alekseik@netflix.com>2019-05-15 02:13:57 +0300
commit10d7e01ee9618a42cb658a07d692557a03456fe5 (patch)
treeb000e346fe579656d9d32cf2479faceedbb7e04b /src/inspector_agent.cc
parent23ef3e4cfb8da65b205e6895947375e5284bebdc (diff)
inspector: added NodeRuntime domain
Historically Node process sends Runtime.executionContextDestroyed with main context as argument when it is finished. This approach has some disadvantages. V8 prevents running some protocol command on destroyed contexts, e.g. Runtime.evaluate will return an error or Debugger.enable won't return a list of scripts. Both command might be useful for different tools, e.g. tool runs Profiler.startPreciseCoverage and at the end of node process it would like to get list of all scripts to match data to source code. Or some tooling frontend would like to provide capabilities to run commands in console when node process is finished to allow user to inspect state of the program at exit. This PR adds new domain: NodeRuntime. After NodeRuntime.notifyWhenWaitingForDisconnect is enabled by at least one client, node will send NodeRuntime.waitingForDebuggerToDisconnect event instead of Runtime.executionContextDestroyed. Based on this signal any protocol client can capture all required information and then disconnect its session. PR-URL: https://github.com/nodejs/node/pull/27600 Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'src/inspector_agent.cc')
-rw-r--r--src/inspector_agent.cc46
1 files changed, 41 insertions, 5 deletions
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
index d82e88d6123..d8b5d01a285 100644
--- a/src/inspector_agent.cc
+++ b/src/inspector_agent.cc
@@ -2,6 +2,7 @@
#include "inspector/main_thread_interface.h"
#include "inspector/node_string.h"
+#include "inspector/runtime_agent.h"
#include "inspector/tracing_agent.h"
#include "inspector/worker_agent.h"
#include "inspector/worker_inspector.h"
@@ -221,7 +222,8 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
std::unique_ptr<InspectorSessionDelegate> delegate,
std::shared_ptr<MainThreadHandle> main_thread_,
bool prevent_shutdown)
- : delegate_(std::move(delegate)), prevent_shutdown_(prevent_shutdown) {
+ : delegate_(std::move(delegate)), prevent_shutdown_(prevent_shutdown),
+ retaining_context_(false) {
session_ = inspector->connect(1, this, StringView());
node_dispatcher_ = std::make_unique<protocol::UberDispatcher>(this);
tracing_agent_ =
@@ -229,6 +231,8 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
tracing_agent_->Wire(node_dispatcher_.get());
worker_agent_ = std::make_unique<protocol::WorkerAgent>(worker_manager);
worker_agent_->Wire(node_dispatcher_.get());
+ runtime_agent_ = std::make_unique<protocol::RuntimeAgent>(env);
+ runtime_agent_->Wire(node_dispatcher_.get());
}
~ChannelImpl() override {
@@ -236,6 +240,8 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
tracing_agent_.reset(); // Dispose before the dispatchers
worker_agent_->disable();
worker_agent_.reset(); // Dispose before the dispatchers
+ runtime_agent_->disable();
+ runtime_agent_.reset(); // Dispose before the dispatchers
}
void dispatchProtocolMessage(const StringView& message) {
@@ -264,6 +270,15 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
return prevent_shutdown_;
}
+ bool notifyWaitingForDisconnect() {
+ retaining_context_ = runtime_agent_->notifyWaitingForDisconnect();
+ return retaining_context_;
+ }
+
+ bool retainingContext() {
+ return retaining_context_;
+ }
+
private:
void sendResponse(
int callId,
@@ -303,12 +318,14 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
DCHECK(false);
}
+ std::unique_ptr<protocol::RuntimeAgent> runtime_agent_;
std::unique_ptr<protocol::TracingAgent> tracing_agent_;
std::unique_ptr<protocol::WorkerAgent> worker_agent_;
std::unique_ptr<InspectorSessionDelegate> delegate_;
std::unique_ptr<v8_inspector::V8InspectorSession> session_;
std::unique_ptr<protocol::UberDispatcher> node_dispatcher_;
bool prevent_shutdown_;
+ bool retaining_context_;
};
class InspectorTimer {
@@ -511,7 +528,18 @@ class NodeInspectorClient : public V8InspectorClient {
}
void disconnectFrontend(int session_id) {
- channels_.erase(session_id);
+ auto it = channels_.find(session_id);
+ if (it == channels_.end())
+ return;
+ bool retaining_context = it->second->retainingContext();
+ channels_.erase(it);
+ if (retaining_context) {
+ for (const auto& id_channel : channels_) {
+ if (id_channel.second->retainingContext())
+ return;
+ }
+ contextDestroyed(env_->context());
+ }
}
void dispatchMessageFromFrontend(int session_id, const StringView& message) {
@@ -608,6 +636,15 @@ class NodeInspectorClient : public V8InspectorClient {
return false;
}
+ bool notifyWaitingForDisconnect() {
+ bool retaining_context = false;
+ for (const auto& id_channel : channels_) {
+ if (id_channel.second->notifyWaitingForDisconnect())
+ retaining_context = true;
+ }
+ return retaining_context;
+ }
+
std::shared_ptr<MainThreadHandle> getThreadHandle() {
if (interface_ == nullptr) {
interface_.reset(new MainThreadInterface(
@@ -774,9 +811,8 @@ void Agent::WaitForDisconnect() {
fprintf(stderr, "Waiting for the debugger to disconnect...\n");
fflush(stderr);
}
- // TODO(addaleax): Maybe this should use an at-exit hook for the Environment
- // or something similar?
- client_->contextDestroyed(parent_env_->context());
+ if (!client_->notifyWaitingForDisconnect())
+ client_->contextDestroyed(parent_env_->context());
if (io_ != nullptr) {
io_->StopAcceptingNewConnections();
client_->waitForIoShutdown();