src: reorganize inspector and diagnostics initialization
- Split the initialization of the inspector and other diagnostics into `Environment::InitializeInspector()` and `Environment::InitializeDiagnostics()` - these need to be reinitialized separately after snapshot deserialization. - Do not store worker url alongside the inspector parent handle, instead just get it from the handle. - Rename `Worker::profiler_idle_notifier_started_` to `Worker::start_profiler_idle_notifier_` because it stores the state inherited from the parent env to use for initializing itself. PR-URL: https://github.com/nodejs/node/pull/27539 Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
a1a690e07c
commit
a0d86befb5
@ -349,8 +349,6 @@ Environment::Environment(IsolateData* isolate_data,
|
|||||||
credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats, this);
|
credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats, this);
|
||||||
set_debug_categories(debug_cats, true);
|
set_debug_categories(debug_cats, true);
|
||||||
|
|
||||||
isolate()->GetHeapProfiler()->AddBuildEmbedderGraphCallback(
|
|
||||||
BuildEmbedderGraph, this);
|
|
||||||
if (options_->no_force_async_hooks_checks) {
|
if (options_->no_force_async_hooks_checks) {
|
||||||
async_hooks_.no_force_checks();
|
async_hooks_.no_force_checks();
|
||||||
}
|
}
|
||||||
|
11
src/env.h
11
src/env.h
@ -75,6 +75,10 @@ class V8CoverageConnection;
|
|||||||
class V8CpuProfilerConnection;
|
class V8CpuProfilerConnection;
|
||||||
class V8HeapProfilerConnection;
|
class V8HeapProfilerConnection;
|
||||||
} // namespace profiler
|
} // namespace profiler
|
||||||
|
|
||||||
|
namespace inspector {
|
||||||
|
class ParentInspectorHandle;
|
||||||
|
}
|
||||||
#endif // HAVE_INSPECTOR
|
#endif // HAVE_INSPECTOR
|
||||||
|
|
||||||
namespace worker {
|
namespace worker {
|
||||||
@ -797,6 +801,13 @@ class Environment : public MemoryRetainer {
|
|||||||
void MemoryInfo(MemoryTracker* tracker) const override;
|
void MemoryInfo(MemoryTracker* tracker) const override;
|
||||||
|
|
||||||
void CreateProperties();
|
void CreateProperties();
|
||||||
|
// Should be called before InitializeInspector()
|
||||||
|
void InitializeDiagnostics();
|
||||||
|
#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
|
||||||
|
// If the environment is created for a worker, pass parent_handle and
|
||||||
|
// the ownership if transferred into the Environment.
|
||||||
|
int InitializeInspector(inspector::ParentInspectorHandle* parent_handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
inline size_t async_callback_scope_depth() const;
|
inline size_t async_callback_scope_depth() const;
|
||||||
inline void PushAsyncCallbackScope();
|
inline void PushAsyncCallbackScope();
|
||||||
|
@ -60,6 +60,7 @@ class ParentInspectorHandle {
|
|||||||
bool WaitForConnect() {
|
bool WaitForConnect() {
|
||||||
return wait_;
|
return wait_;
|
||||||
}
|
}
|
||||||
|
const std::string& url() const { return url_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int id_;
|
int id_;
|
||||||
|
65
src/node.cc
65
src/node.cc
@ -47,6 +47,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
|
#include "inspector_agent.h"
|
||||||
#include "inspector_io.h"
|
#include "inspector_io.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -59,6 +60,10 @@
|
|||||||
#endif // NODE_USE_V8_PLATFORM
|
#endif // NODE_USE_V8_PLATFORM
|
||||||
#include "v8-profiler.h"
|
#include "v8-profiler.h"
|
||||||
|
|
||||||
|
#if HAVE_INSPECTOR
|
||||||
|
#include "inspector/worker_inspector.h" // ParentInspectorHandle
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NODE_ENABLE_VTUNE_PROFILING
|
#ifdef NODE_ENABLE_VTUNE_PROFILING
|
||||||
#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
|
#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
|
||||||
#endif
|
#endif
|
||||||
@ -136,7 +141,6 @@ using v8::Local;
|
|||||||
using v8::Maybe;
|
using v8::Maybe;
|
||||||
using v8::MaybeLocal;
|
using v8::MaybeLocal;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::Script;
|
|
||||||
using v8::String;
|
using v8::String;
|
||||||
using v8::Undefined;
|
using v8::Undefined;
|
||||||
using v8::V8;
|
using v8::V8;
|
||||||
@ -228,6 +232,51 @@ MaybeLocal<Value> ExecuteBootstrapper(Environment* env,
|
|||||||
return scope.EscapeMaybe(result);
|
return scope.EscapeMaybe(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
|
||||||
|
int Environment::InitializeInspector(
|
||||||
|
inspector::ParentInspectorHandle* parent_handle) {
|
||||||
|
std::string inspector_path;
|
||||||
|
if (parent_handle != nullptr) {
|
||||||
|
DCHECK(!is_main_thread());
|
||||||
|
inspector_path = parent_handle->url();
|
||||||
|
inspector_agent_->SetParentHandle(
|
||||||
|
std::unique_ptr<inspector::ParentInspectorHandle>(parent_handle));
|
||||||
|
} else {
|
||||||
|
inspector_path = argv_.size() > 1 ? argv_[1].c_str() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(!inspector_agent_->IsListening());
|
||||||
|
// Inspector agent can't fail to start, but if it was configured to listen
|
||||||
|
// right away on the websocket port and fails to bind/etc, this will return
|
||||||
|
// false.
|
||||||
|
inspector_agent_->Start(inspector_path,
|
||||||
|
options_->debug_options(),
|
||||||
|
inspector_host_port(),
|
||||||
|
is_main_thread());
|
||||||
|
if (options_->debug_options().inspector_enabled &&
|
||||||
|
!inspector_agent_->IsListening()) {
|
||||||
|
return 12; // Signal internal error
|
||||||
|
}
|
||||||
|
|
||||||
|
profiler::StartProfilers(this);
|
||||||
|
|
||||||
|
if (options_->debug_options().break_node_first_line) {
|
||||||
|
inspector_agent_->PauseOnNextJavascriptStatement("Break at bootstrap");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif // HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
|
||||||
|
|
||||||
|
void Environment::InitializeDiagnostics() {
|
||||||
|
isolate_->GetHeapProfiler()->AddBuildEmbedderGraphCallback(
|
||||||
|
Environment::BuildEmbedderGraph, this);
|
||||||
|
|
||||||
|
#if defined HAVE_DTRACE || defined HAVE_ETW
|
||||||
|
InitDTrace(this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
MaybeLocal<Value> RunBootstrapping(Environment* env) {
|
MaybeLocal<Value> RunBootstrapping(Environment* env) {
|
||||||
CHECK(!env->has_run_bootstrapping_code());
|
CHECK(!env->has_run_bootstrapping_code());
|
||||||
|
|
||||||
@ -235,17 +284,9 @@ MaybeLocal<Value> RunBootstrapping(Environment* env) {
|
|||||||
Isolate* isolate = env->isolate();
|
Isolate* isolate = env->isolate();
|
||||||
Local<Context> context = env->context();
|
Local<Context> context = env->context();
|
||||||
|
|
||||||
#if HAVE_INSPECTOR
|
|
||||||
profiler::StartProfilers(env);
|
|
||||||
#endif // HAVE_INSPECTOR
|
|
||||||
|
|
||||||
// Add a reference to the global object
|
// Add a reference to the global object
|
||||||
Local<Object> global = context->Global();
|
Local<Object> global = context->Global();
|
||||||
|
|
||||||
#if defined HAVE_DTRACE || defined HAVE_ETW
|
|
||||||
InitDTrace(env);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Local<Object> process = env->process_object();
|
Local<Object> process = env->process_object();
|
||||||
|
|
||||||
// Setting global properties for the bootstrappers to use:
|
// Setting global properties for the bootstrappers to use:
|
||||||
@ -255,12 +296,6 @@ MaybeLocal<Value> RunBootstrapping(Environment* env) {
|
|||||||
global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global)
|
global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global)
|
||||||
.Check();
|
.Check();
|
||||||
|
|
||||||
#if HAVE_INSPECTOR
|
|
||||||
if (env->options()->debug_options().break_node_first_line) {
|
|
||||||
env->inspector_agent()->PauseOnNextJavascriptStatement(
|
|
||||||
"Break at bootstrap");
|
|
||||||
}
|
|
||||||
#endif // HAVE_INSPECTOR
|
|
||||||
|
|
||||||
// Create binding loaders
|
// Create binding loaders
|
||||||
std::vector<Local<String>> loaders_params = {
|
std::vector<Local<String>> loaders_params = {
|
||||||
|
@ -194,27 +194,16 @@ std::unique_ptr<Environment> NodeMainInstance::CreateMainEnvironment(
|
|||||||
Environment::kOwnsProcessState |
|
Environment::kOwnsProcessState |
|
||||||
Environment::kOwnsInspector));
|
Environment::kOwnsInspector));
|
||||||
env->InitializeLibuv(per_process::v8_is_profiling);
|
env->InitializeLibuv(per_process::v8_is_profiling);
|
||||||
|
env->InitializeDiagnostics();
|
||||||
|
|
||||||
|
// TODO(joyeecheung): when we snapshot the bootstrapped context,
|
||||||
|
// the inspector and diagnostics setup should after after deserialization.
|
||||||
#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
|
#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
|
||||||
CHECK(!env->inspector_agent()->IsListening());
|
*exit_code = env->InitializeInspector(nullptr);
|
||||||
// Inspector agent can't fail to start, but if it was configured to listen
|
#endif
|
||||||
// right away on the websocket port and fails to bind/etc, this will return
|
if (*exit_code != 0) {
|
||||||
// false.
|
|
||||||
env->inspector_agent()->Start(args_.size() > 1 ? args_[1].c_str() : "",
|
|
||||||
env->options()->debug_options(),
|
|
||||||
env->inspector_host_port(),
|
|
||||||
true);
|
|
||||||
if (env->options()->debug_options().inspector_enabled &&
|
|
||||||
!env->inspector_agent()->IsListening()) {
|
|
||||||
*exit_code = 12; // Signal internal error.
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// inspector_enabled can't be true if !HAVE_INSPECTOR or
|
|
||||||
// !NODE_USE_V8_PLATFORM
|
|
||||||
// - the option parser should not allow that.
|
|
||||||
CHECK(!env->options()->debug_options().inspector_enabled);
|
|
||||||
#endif // HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
|
|
||||||
|
|
||||||
if (RunBootstrapping(env.get()).IsEmpty()) {
|
if (RunBootstrapping(env.get()).IsEmpty()) {
|
||||||
*exit_code = 1;
|
*exit_code = 1;
|
||||||
|
@ -42,17 +42,6 @@ namespace worker {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
|
#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
|
||||||
void StartWorkerInspector(
|
|
||||||
Environment* child,
|
|
||||||
std::unique_ptr<inspector::ParentInspectorHandle> parent_handle,
|
|
||||||
const std::string& url) {
|
|
||||||
child->inspector_agent()->SetParentHandle(std::move(parent_handle));
|
|
||||||
child->inspector_agent()->Start(url,
|
|
||||||
child->options()->debug_options(),
|
|
||||||
child->inspector_host_port(),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WaitForWorkerInspectorToStop(Environment* child) {
|
void WaitForWorkerInspectorToStop(Environment* child) {
|
||||||
child->inspector_agent()->WaitForDisconnect();
|
child->inspector_agent()->WaitForDisconnect();
|
||||||
child->inspector_agent()->Stop();
|
child->inspector_agent()->Stop();
|
||||||
@ -67,11 +56,10 @@ Worker::Worker(Environment* env,
|
|||||||
std::shared_ptr<PerIsolateOptions> per_isolate_opts,
|
std::shared_ptr<PerIsolateOptions> per_isolate_opts,
|
||||||
std::vector<std::string>&& exec_argv)
|
std::vector<std::string>&& exec_argv)
|
||||||
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_WORKER),
|
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_WORKER),
|
||||||
url_(url),
|
|
||||||
per_isolate_opts_(per_isolate_opts),
|
per_isolate_opts_(per_isolate_opts),
|
||||||
exec_argv_(exec_argv),
|
exec_argv_(exec_argv),
|
||||||
platform_(env->isolate_data()->platform()),
|
platform_(env->isolate_data()->platform()),
|
||||||
profiler_idle_notifier_started_(env->profiler_idle_notifier_started()),
|
start_profiler_idle_notifier_(env->profiler_idle_notifier_started()),
|
||||||
thread_id_(Environment::AllocateThreadId()),
|
thread_id_(Environment::AllocateThreadId()),
|
||||||
env_vars_(env->env_vars()) {
|
env_vars_(env->env_vars()) {
|
||||||
Debug(this, "Creating new worker instance with thread id %llu", thread_id_);
|
Debug(this, "Creating new worker instance with thread id %llu", thread_id_);
|
||||||
@ -265,7 +253,7 @@ void Worker::Run() {
|
|||||||
env_->set_abort_on_uncaught_exception(false);
|
env_->set_abort_on_uncaught_exception(false);
|
||||||
env_->set_worker_context(this);
|
env_->set_worker_context(this);
|
||||||
|
|
||||||
env_->InitializeLibuv(profiler_idle_notifier_started_);
|
env_->InitializeLibuv(start_profiler_idle_notifier_);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Mutex::ScopedLock lock(mutex_);
|
Mutex::ScopedLock lock(mutex_);
|
||||||
@ -275,13 +263,11 @@ void Worker::Run() {
|
|||||||
Debug(this, "Created Environment for worker with id %llu", thread_id_);
|
Debug(this, "Created Environment for worker with id %llu", thread_id_);
|
||||||
if (is_stopped()) return;
|
if (is_stopped()) return;
|
||||||
{
|
{
|
||||||
|
env_->InitializeDiagnostics();
|
||||||
#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
|
#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
|
||||||
StartWorkerInspector(env_.get(),
|
env_->InitializeInspector(inspector_parent_handle_.release());
|
||||||
std::move(inspector_parent_handle_),
|
|
||||||
url_);
|
|
||||||
#endif
|
|
||||||
inspector_started = true;
|
inspector_started = true;
|
||||||
|
#endif
|
||||||
HandleScope handle_scope(isolate_);
|
HandleScope handle_scope(isolate_);
|
||||||
AsyncCallbackScope callback_scope(env_.get());
|
AsyncCallbackScope callback_scope(env_.get());
|
||||||
env_->async_hooks()->push_async_ids(1, 0);
|
env_->async_hooks()->push_async_ids(1, 0);
|
||||||
|
@ -54,7 +54,6 @@ class Worker : public AsyncWrap {
|
|||||||
private:
|
private:
|
||||||
void OnThreadStopped();
|
void OnThreadStopped();
|
||||||
void CreateEnvMessagePort(Environment* env);
|
void CreateEnvMessagePort(Environment* env);
|
||||||
const std::string url_;
|
|
||||||
|
|
||||||
std::shared_ptr<PerIsolateOptions> per_isolate_opts_;
|
std::shared_ptr<PerIsolateOptions> per_isolate_opts_;
|
||||||
std::vector<std::string> exec_argv_;
|
std::vector<std::string> exec_argv_;
|
||||||
@ -62,7 +61,7 @@ class Worker : public AsyncWrap {
|
|||||||
|
|
||||||
MultiIsolatePlatform* platform_;
|
MultiIsolatePlatform* platform_;
|
||||||
v8::Isolate* isolate_ = nullptr;
|
v8::Isolate* isolate_ = nullptr;
|
||||||
bool profiler_idle_notifier_started_;
|
bool start_profiler_idle_notifier_;
|
||||||
uv_thread_t tid_;
|
uv_thread_t tid_;
|
||||||
|
|
||||||
#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
|
#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user