Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inspector: support for worker inspection in chrome devtools #56759

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

islandryu
Copy link
Contributor

@islandryu islandryu commented Jan 25, 2025

This PR introduces support for inspecting workers in Chrome DevTools. I would like to gather some feedback to confirm whether there seem to be no issues with this approach. If the approach in this PR deviates significantly from the desired direction, I am happy to close it. However, if the general approach seems acceptable, I will proceed with this PR and submit a change request to Chrome DevTools.


Summary of Changes

This implementation uses the attachedToTarget event to notify the creation of workers. More details on the protocol can be found [here](https://chromedevtools.github.io/devtools-protocol/tot/Target/#event-attachedToTarget).

This sequence is how to worker inspection works.
When a worker is created, attachedToTarget is notified to the server, and the server thread allocates methods from the client to the appropriate thread based on the sessionId.

sequenceDiagram
    participant DevtoolClient as DevTool Client
    participant ServerThread as Server Thread
    participant MainThread as Main Thread
    participant WorkerThread as Worker Thread

    DevtoolClient ->> ServerThread: attach
    ServerThread ->> MainThread: attach

    MainThread ->> MainThread: execute program

    MainThread ->> WorkerThread: create worker

    MainThread ->> ServerThread: attachedToTarget
    ServerThread ->> DevtoolClient: attachedToTarget

    DevtoolClient ->> ServerThread: debugger method
    ServerThread ->> ServerThread: Check which thread to send to by sessionId
    ServerThread ->> WorkerThread: Send to main thread or worker thread
Loading

How to Verify

Currently, dedicated DevTools for Node.js do not support worker targets. For verification, use inspector.html:

devtools://devtools/bundled/inspector.html?ws=127.0.0.1:9229/(sessionId)

Steps:

  1. Start the Node.js process with the following command:
    node --inspect-brk --experimental-worker-inspection index.js
  2. Use the following index.js and worker.js files for testing:

index.js:

const { Worker } = require('worker_threads');
const workerPath =  __dirname + '/worker.js';
const worker = new Worker(workerPath);

worker.js:

console.log("worker thread");
process.on('exit', () => {
  console.log('Worker1: Exiting...');
});

Currently, the results of console.log within the worker are being sent twice, but I'm working on fixing this issue.


Additional Information

The approach used in this PR follows the CDP (Chrome DevTools Protocol) and is different from the Node.js worker debugging protocol used in VSCode. It adheres to the existing CDP protocol to ensure compatibility.

fix #56343

@nodejs-github-bot
Copy link
Collaborator

nodejs-github-bot commented Jan 25, 2025

Review requested:

  • @nodejs/gyp
  • @nodejs/inspector

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Jan 25, 2025
}));
}

test().then(common.mustCall());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test() function wrapper is no longer needed: by default, an unhandled promise rejection makes the process exit with a non-zero exit code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.
I removed the wrapper.

@legendecas
Copy link
Member

Tracing the history discussion, it would be great to have @eugeneo, @pavelfeldman and @dgozman weighing in this work

@legendecas
Copy link
Member

Confirmed with Chrome DevTools team (dsv@, caseq@) that they are good with Node.js implementing the Target domain for worker discovery, or implementing NodeWorker domain support in Chrome DevTools frontend.

As the Target domain in this PR is behind the flag --experimental-worker-inspection, I believe it is fine to go ahead. Thank you for working on this!

@legendecas legendecas added the inspector Issues and PRs related to the V8 inspector protocol label Jan 29, 2025
@legendecas legendecas linked an issue Jan 29, 2025 that may be closed by this pull request
@islandryu
Copy link
Contributor Author

Confirmed with Chrome DevTools team (dsv@, caseq@) that they are good with Node.js implementing the Target domain for worker discovery, or implementing NodeWorker domain support in Chrome DevTools frontend.

As the Target domain in this PR is behind the flag --experimental-worker-inspection, I believe it is fine to go ahead. Thank you for working on this!

Thank you!
I'll resolve the conflicts, make a few minor fixes, and then open the PR.

@islandryu islandryu changed the title [WIP] inspector: support for worker inspection in chrome devtools inspector: support for worker inspection in chrome devtools Jan 30, 2025
@islandryu islandryu marked this pull request as ready for review January 30, 2025 11:07
@islandryu islandryu marked this pull request as draft January 30, 2025 12:06
@islandryu islandryu marked this pull request as ready for review January 30, 2025 12:15
Copy link

codecov bot commented Jan 30, 2025

Codecov Report

Attention: Patch coverage is 94.73684% with 8 lines in your changes missing coverage. Please review.

Project coverage is 89.16%. Comparing base (0edeafd) to head (b669db4).
Report is 108 commits behind head on main.

Files with missing lines Patch % Lines
src/inspector/target_agent.cc 95.83% 0 Missing and 3 partials ⚠️
src/inspector_io.cc 93.18% 0 Missing and 3 partials ⚠️
src/inspector_agent.cc 91.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #56759      +/-   ##
==========================================
- Coverage   89.21%   89.16%   -0.05%     
==========================================
  Files         663      667       +4     
  Lines      192001   193305    +1304     
  Branches    36923    37204     +281     
==========================================
+ Hits       171290   172358    +1068     
- Misses      13582    13697     +115     
- Partials     7129     7250     +121     
Files with missing lines Coverage Δ
src/inspector/main_thread_interface.h 95.00% <100.00%> (+1.66%) ⬆️
src/inspector/target_agent.h 100.00% <100.00%> (ø)
src/node_options.cc 87.97% <100.00%> (+0.01%) ⬆️
src/node_options.h 98.34% <100.00%> (+<0.01%) ⬆️
src/inspector_agent.cc 79.83% <91.66%> (+0.08%) ⬆️
src/inspector/target_agent.cc 95.83% <95.83%> (ø)
src/inspector_io.cc 92.56% <93.18%> (-0.02%) ⬇️

... and 93 files with indirect coverage changes

@islandryu
Copy link
Contributor Author

Issue to devtools-frontend
https://issues.chromium.org/issues/393746702

const sessionId = '1';
await session.waitForNotification('Target.targetCreated');
await session.waitForNotification((notification) => {
return notification.method === 'Target.attachedToTarget' &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Event Target.attachedToTarget should not be emitted without a Target.setAutoAttach command or Target.attachToTarget command.

Comment on lines +109 to +127
// TODO(islandryu): Currently, setAutoAttach applies the main thread's value to
// all threads. Modify it to be managed per worker thread.
crdtp::DispatchResponse TargetAgent::setAutoAttach(
bool auto_attach, bool wait_for_debugger_on_start) {
auto_attach_ = auto_attach;
wait_for_debugger_on_start_ = wait_for_debugger_on_start;

if (auto_attach) {
for (auto& target : targets_) {
if (!target.attached) {
target.attached = true;
attachedToTarget(target.worker,
target.target_id,
target.type,
target.title,
target.url);
}
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setAutoAttach is implemented.
However, I am not able to determine autoAttach for each related Target and waitForDebuggerOnStart.
I have tried several way, but it was difficult to make the changes without affecting the existing nodeWorker, so I would like to make a TODO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. inspector Issues and PRs related to the V8 inspector protocol lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

--inspect-brk causes code with workers to hang Debug worker_threads
4 participants