diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index b73787174cdc96..328bb55c88f3c9 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -253,6 +253,7 @@ Notable differences inside a Worker environment are: - Execution may stop at any point as a result of [`worker.terminate()`][] being invoked. - IPC channels from parent processes are not accessible. +- The [`trace_events`][] module is not supported. Currently, the following differences also exist until they are addressed: @@ -489,6 +490,7 @@ active handle in the event system. If the worker is already `unref()`ed calling [`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer [Signals events]: process.html#process_signal_events [`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array +[`trace_events`]: tracing.html [browser `MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort [child processes]: child_process.html [HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm diff --git a/lib/trace_events.js b/lib/trace_events.js index bf303c28b7dcdc..878580c67f5a2f 100644 --- a/lib/trace_events.js +++ b/lib/trace_events.js @@ -13,7 +13,8 @@ const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; -if (!hasTracing) +const { isMainThread } = require('internal/worker'); +if (!hasTracing || !isMainThread) throw new ERR_TRACE_EVENTS_UNAVAILABLE(); const { CategorySet, getEnabledCategories } = internalBinding('trace_events'); diff --git a/src/env.cc b/src/env.cc index 76c7e58e276bc8..527058766ac86a 100644 --- a/src/env.cc +++ b/src/env.cc @@ -128,11 +128,22 @@ void InitThreadLocalOnce() { } void Environment::TrackingTraceStateObserver::UpdateTraceCategoryState() { + if (!env_->is_main_thread()) { + // Ideally, we’d have a consistent story that treats all threads/Environment + // instances equally here. However, tracing is essentially global, and this + // callback is callback from whichever thread calls `StartTracing()` or + // `StopTracing()`. The only way to do this in a threadsafe fashion + // seems to be only tracking this from the main thread, and only allowing + // these state modifications from the main thread. + return; + } + env_->trace_category_state()[0] = *TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( TRACING_CATEGORY_NODE1(async_hooks)); Isolate* isolate = env_->isolate(); + HandleScope handle_scope(isolate); Local cb = env_->trace_category_state_function(); if (cb.IsEmpty()) return; diff --git a/src/inspector/tracing_agent.cc b/src/inspector/tracing_agent.cc index 1ad67d9b9e7f71..64bf7457d9f728 100644 --- a/src/inspector/tracing_agent.cc +++ b/src/inspector/tracing_agent.cc @@ -65,6 +65,10 @@ DispatchResponse TracingAgent::start( return DispatchResponse::Error( "Call NodeTracing::end to stop tracing before updating the config"); } + if (!env_->is_main_thread()) { + return DispatchResponse::Error( + "Tracing properties can only be changed through main thread sessions"); + } std::set categories_set; protocol::Array* categories =