Skip to content

Commit

Permalink
src: reorganize inspector and diagnostics initialization
Browse files Browse the repository at this point in the history
- 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: #27539
Reviewed-By: Anna Henningsen <[email protected]>
  • Loading branch information
joyeecheung authored and BridgeAR committed Jun 17, 2019
1 parent c086736 commit c20c6e5
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 55 deletions.
2 changes: 0 additions & 2 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,6 @@ Environment::Environment(IsolateData* isolate_data,
credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats, this);
set_debug_categories(debug_cats, true);

isolate()->GetHeapProfiler()->AddBuildEmbedderGraphCallback(
BuildEmbedderGraph, this);
if (options_->no_force_async_hooks_checks) {
async_hooks_.no_force_checks();
}
Expand Down
11 changes: 11 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ class V8CoverageConnection;
class V8CpuProfilerConnection;
class V8HeapProfilerConnection;
} // namespace profiler

namespace inspector {
class ParentInspectorHandle;
}
#endif // HAVE_INSPECTOR

namespace worker {
Expand Down Expand Up @@ -797,6 +801,13 @@ class Environment : public MemoryRetainer {
void MemoryInfo(MemoryTracker* tracker) const override;

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 void PushAsyncCallbackScope();
Expand Down
1 change: 1 addition & 0 deletions src/inspector/worker_inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class ParentInspectorHandle {
bool WaitForConnect() {
return wait_;
}
const std::string& url() const { return url_; }

private:
int id_;
Expand Down
65 changes: 50 additions & 15 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#endif

#if HAVE_INSPECTOR
#include "inspector_agent.h"
#include "inspector_io.h"
#endif

Expand All @@ -59,6 +60,10 @@
#endif // NODE_USE_V8_PLATFORM
#include "v8-profiler.h"

#if HAVE_INSPECTOR
#include "inspector/worker_inspector.h" // ParentInspectorHandle
#endif

#ifdef NODE_ENABLE_VTUNE_PROFILING
#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
#endif
Expand Down Expand Up @@ -125,7 +130,6 @@ using v8::Local;
using v8::Maybe;
using v8::MaybeLocal;
using v8::Object;
using v8::Script;
using v8::String;
using v8::Undefined;
using v8::V8;
Expand Down Expand Up @@ -222,24 +226,61 @@ MaybeLocal<Value> ExecuteBootstrapper(Environment* env,
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) {
CHECK(!env->has_run_bootstrapping_code());

EscapableHandleScope scope(env->isolate());
Isolate* isolate = env->isolate();
Local<Context> context = env->context();

#if HAVE_INSPECTOR
profiler::StartProfilers(env);
#endif // HAVE_INSPECTOR

// Add a reference to the global object
Local<Object> global = context->Global();

#if defined HAVE_DTRACE || defined HAVE_ETW
InitDTrace(env);
#endif

Local<Object> process = env->process_object();

// Setting global properties for the bootstrappers to use:
Expand All @@ -249,12 +290,6 @@ MaybeLocal<Value> RunBootstrapping(Environment* env) {
global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global)
.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
std::vector<Local<String>> loaders_params = {
Expand Down
23 changes: 6 additions & 17 deletions src/node_main_instance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,27 +194,16 @@ std::unique_ptr<Environment> NodeMainInstance::CreateMainEnvironment(
Environment::kOwnsProcessState |
Environment::kOwnsInspector));
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
CHECK(!env->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.
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.
*exit_code = env->InitializeInspector(nullptr);
#endif
if (*exit_code != 0) {
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()) {
*exit_code = 1;
Expand Down
24 changes: 5 additions & 19 deletions src/node_worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,6 @@ namespace worker {
namespace {

#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) {
child->inspector_agent()->WaitForDisconnect();
child->inspector_agent()->Stop();
Expand All @@ -67,11 +56,10 @@ Worker::Worker(Environment* env,
std::shared_ptr<PerIsolateOptions> per_isolate_opts,
std::vector<std::string>&& exec_argv)
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_WORKER),
url_(url),
per_isolate_opts_(per_isolate_opts),
exec_argv_(exec_argv),
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()),
env_vars_(env->env_vars()) {
Debug(this, "Creating new worker instance with thread id %llu", thread_id_);
Expand Down Expand Up @@ -265,7 +253,7 @@ void Worker::Run() {
env_->set_abort_on_uncaught_exception(false);
env_->set_worker_context(this);

env_->InitializeLibuv(profiler_idle_notifier_started_);
env_->InitializeLibuv(start_profiler_idle_notifier_);
}
{
Mutex::ScopedLock lock(mutex_);
Expand All @@ -275,13 +263,11 @@ void Worker::Run() {
Debug(this, "Created Environment for worker with id %llu", thread_id_);
if (is_stopped()) return;
{
env_->InitializeDiagnostics();
#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
StartWorkerInspector(env_.get(),
std::move(inspector_parent_handle_),
url_);
#endif
env_->InitializeInspector(inspector_parent_handle_.release());
inspector_started = true;

#endif
HandleScope handle_scope(isolate_);
AsyncCallbackScope callback_scope(env_.get());
env_->async_hooks()->push_async_ids(1, 0);
Expand Down
3 changes: 1 addition & 2 deletions src/node_worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,14 @@ class Worker : public AsyncWrap {
private:
void OnThreadStopped();
void CreateEnvMessagePort(Environment* env);
const std::string url_;

std::shared_ptr<PerIsolateOptions> per_isolate_opts_;
std::vector<std::string> exec_argv_;
std::vector<std::string> argv_;

MultiIsolatePlatform* platform_;
v8::Isolate* isolate_ = nullptr;
bool profiler_idle_notifier_started_;
bool start_profiler_idle_notifier_;
uv_thread_t tid_;

#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR
Expand Down

0 comments on commit c20c6e5

Please sign in to comment.