From 68b3e46fbf88ad81f50f68c7f0c725dc06c8beb0 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Tue, 18 Sep 2018 14:04:45 -0700 Subject: [PATCH] trace_events: destroy platform before tracing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For safer shutdown, we should destroy the platform – and background threads - before the tracing infrastructure is destroyed. This change fixes the relative order of NodePlatform disposition and the tracing agent shutting down. This matches the nesting order for startup. Make the tracing agent own the tracing controller instead of platform to match the above. Fixes: https://github.com/nodejs/node/issues/22865 PR-URL: https://github.com/nodejs/node/pull/22938 Reviewed-By: Eugene Ostroukhov Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- src/node.cc | 5 ++++- src/node_platform.cc | 7 +++---- src/node_platform.h | 2 +- src/tracing/agent.cc | 11 +++++------ src/tracing/agent.h | 6 ++++-- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/node.cc b/src/node.cc index b8da26fa735825..6250acfd5d540f 100644 --- a/src/node.cc +++ b/src/node.cc @@ -292,15 +292,18 @@ static struct { controller->AddTraceStateObserver(new NodeTraceStateObserver(controller)); tracing::TraceEventHelper::SetTracingController(controller); StartTracingAgent(); + // Tracing must be initialized before platform threads are created. platform_ = new NodePlatform(thread_pool_size, controller); V8::InitializePlatform(platform_); } void Dispose() { - tracing_agent_.reset(nullptr); platform_->Shutdown(); delete platform_; platform_ = nullptr; + // Destroy tracing after the platform (and platform threads) have been + // stopped. + tracing_agent_.reset(nullptr); } void DrainVMTasks(Isolate* isolate) { diff --git a/src/node_platform.cc b/src/node_platform.cc index b583ce85423fb1..278c1684835f7f 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -283,10 +283,9 @@ int PerIsolatePlatformData::unref() { NodePlatform::NodePlatform(int thread_pool_size, TracingController* tracing_controller) { if (tracing_controller) { - tracing_controller_.reset(tracing_controller); + tracing_controller_ = tracing_controller; } else { - TracingController* controller = new TracingController(); - tracing_controller_.reset(controller); + tracing_controller_ = new TracingController(); } worker_thread_task_runner_ = std::make_shared(thread_pool_size); @@ -456,7 +455,7 @@ double NodePlatform::CurrentClockTimeMillis() { } TracingController* NodePlatform::GetTracingController() { - return tracing_controller_.get(); + return tracing_controller_; } template diff --git a/src/node_platform.h b/src/node_platform.h index 197d5cee3968a7..c926c17852878a 100644 --- a/src/node_platform.h +++ b/src/node_platform.h @@ -158,7 +158,7 @@ class NodePlatform : public MultiIsolatePlatform { std::unordered_map> per_isolate_; - std::unique_ptr tracing_controller_; + v8::TracingController* tracing_controller_; std::shared_ptr worker_thread_task_runner_; }; diff --git a/src/tracing/agent.cc b/src/tracing/agent.cc index 5a4d637bda0356..fd5cb3387b14ae 100644 --- a/src/tracing/agent.cc +++ b/src/tracing/agent.cc @@ -48,8 +48,7 @@ using v8::platform::tracing::TraceConfig; using v8::platform::tracing::TraceWriter; using std::string; -Agent::Agent() { - tracing_controller_ = new TracingController(); +Agent::Agent() : tracing_controller_(new TracingController()) { tracing_controller_->Initialize(nullptr); CHECK_EQ(uv_loop_init(&tracing_loop_), 0); @@ -117,7 +116,7 @@ AgentWriterHandle Agent::AddClient( use_categories = &categories_with_default; } - ScopedSuspendTracing suspend(tracing_controller_, this); + ScopedSuspendTracing suspend(tracing_controller_.get(), this); int id = next_writer_id_++; AsyncTraceWriter* raw = writer.get(); writers_[id] = std::move(writer); @@ -157,7 +156,7 @@ void Agent::Disconnect(int client) { Mutex::ScopedLock lock(initialize_writer_mutex_); to_be_initialized_.erase(writers_[client].get()); } - ScopedSuspendTracing suspend(tracing_controller_, this); + ScopedSuspendTracing suspend(tracing_controller_.get(), this); writers_.erase(client); categories_.erase(client); } @@ -166,13 +165,13 @@ void Agent::Enable(int id, const std::set& categories) { if (categories.empty()) return; - ScopedSuspendTracing suspend(tracing_controller_, this, + ScopedSuspendTracing suspend(tracing_controller_.get(), this, id != kDefaultHandleId); categories_[id].insert(categories.begin(), categories.end()); } void Agent::Disable(int id, const std::set& categories) { - ScopedSuspendTracing suspend(tracing_controller_, this, + ScopedSuspendTracing suspend(tracing_controller_.get(), this, id != kDefaultHandleId); std::multiset& writer_categories = categories_[id]; for (const std::string& category : categories) { diff --git a/src/tracing/agent.h b/src/tracing/agent.h index e79480a0369ff7..e9f52abe647a2d 100644 --- a/src/tracing/agent.h +++ b/src/tracing/agent.h @@ -70,7 +70,9 @@ class Agent { Agent(); ~Agent(); - TracingController* GetTracingController() { return tracing_controller_; } + TracingController* GetTracingController() { + return tracing_controller_.get(); + } enum UseDefaultCategoryMode { kUseDefaultCategories, @@ -121,7 +123,7 @@ class Agent { // These maps store the original arguments to AddClient(), by id. std::unordered_map> categories_; std::unordered_map> writers_; - TracingController* tracing_controller_ = nullptr; + std::unique_ptr tracing_controller_; // Variables related to initializing per-event-loop properties of individual // writers, such as libuv handles.