Skip to content

Debug worker_threads #26609

Description

@cevek

There is no possible to debug worker threads, only through event messages to main thread
You can't step into this worker in the chrome dev tools

const worker = new Worker('./worker.js', {});

debugger statements also don't work inside thread

Activity

  1. added
    workerIssues and PRs related to the worker_threads module and Worker API.
    on Mar 12, 2019
  2. added
    inspectorIssues and PRs related to the V8 inspector protocol.
    on Mar 12, 2019
  3. addaleax commented on Mar 12, 2019

    @addaleax
    Member

    Fwiw, I recently wrote @eugeneo an email about this. We implemented something similar to the Target domain that Chrome uses, but under a different name. I don’t know if the plan is for Devtools to use the Node.js-specific domain, or for us to eventually use the Target domain as well.

    /cc @nodejs/v8-inspector

  4. ofrobots commented on Mar 13, 2019

    @ofrobots
    Contributor
  5. pavelfeldman commented on Mar 13, 2019

    @pavelfeldman
    Contributor

    @aslushnikov , @a1ph, do you have cycles to look at it?

  6. pavelfeldman commented on Mar 13, 2019

    @pavelfeldman
    Contributor

    @ak239 , anyone? :) Now that we have the flattened session support settled in chrome land, we can probably name this domain Target and introduce the flattened sessionId dance in Node.

  7. gauravmahto commented on Jul 14, 2019

    @gauravmahto

    NDB has added support for worker_threads. Do we expect something similar in future?
    GoogleChromeLabs/ndb#281

  8. addaleax commented on Jul 14, 2019

    @addaleax
    Member

    @gauravmahto Unfortunately, DevTools does not support this yet, https://bugs.chromium.org/p/chromium/issues/detail?id=968472 is their open issue for this.

  9. alexkozy commented on Jul 14, 2019

    @alexkozy
    Member

    There are two separate things:

    • DevTools folks can adopt ndb code to support workers,
    • additional instrumentation should be added in node to support stepping between main and worker threads.
  10. addaleax commented on Jul 14, 2019

    @addaleax
    Member

    @ak239 What do we need to do for the second part?

  11. gauravmahto commented on Jul 15, 2019

    @gauravmahto

    @ak239 Maybe this helps solve the second part?

  12. alexkozy commented on Jul 15, 2019

    @alexkozy
    Member

    @addaleax there are three methods available on V8Inspector: storeCurrentStackTrace,externalAsyncTaskStarted,externalAsyncTaskFinished.

    To support step into between threads we need to call storeCurrentStackTrace before postMessage, pass V8StackTraceId to another thread and call externalAsyncTaskStarted / finished on another thread when we are processing this message. V8StackTraceId is actually pair of ints. As soon as it is done, when in ndb you press step into on post message, debugger will automatically go to the worker and pause there when worker is about to process message.

    Second idea that is implemented in Chrome, it is doing the same for Worker constructor: store at constructor call, and call started/finished for main worker script. When this one is done, user can click step into worker constructor and go to worker script.

  13. connor4312 commented on Dec 10, 2020

    @connor4312
    Contributor

    In case any debugger implementors come across there -- Node has an extension to the debugger protocol which allows debugging worker threads -- with minimal work given your debugger is already multi-target aware, like VS Code's. However this is not documented anywhere so I have no idea how stable it may be, YMMV.

  14. AriPerkkio commented on Mar 10, 2023

    @AriPerkkio

    Debugging workers with --inspect-brk is possible with some hacky patching. Passing it as execArgv won't work but using node:inspector inside the worker works.

    This does not work:

    import { isMainThread, Worker } from "node:worker_threads";
    import { fileURLToPath } from "node:url";
    
    const filename = fileURLToPath(import.meta.url);
    
    if (isMainThread) {
      new Worker(filename, { execArgv: ["--inspect-brk"] });
    } else {
        debugger; // No stop here
    }

    The node:inspector works. Chrome DevTools stop at the debugger.

    import { isMainThread, Worker } from "node:worker_threads";
    import { fileURLToPath } from "node:url";
    +import inspector from "node:inspector";
    
    const filename = fileURLToPath(import.meta.url);
    
    if (isMainThread) {
      new Worker(filename, { execArgv: ["--inspect-brk"] });
    } else {
    +  if (process.execArgv.includes("--inspect-brk")) {
    +    inspector.open();
    +    inspector.waitForDebugger();
    +  }
    
      debugger; // Stops in worker thread!
    }

    Adding the process.execArgv checks in userland seems like unnecessary work - maybe Node could do this for us?

  15. danieltroger commented on Nov 7, 2023

    @danieltroger

    Debugging workers with --inspect-brk is possible with some hacky patching. Passing it as execArgv won't work but using node:inspector inside the worker works.

    Could you please elaborate on this? Does this enable debugging a worker with chrome devtools? Because I'm not having any success - the worker doesn't show up in chrome after executing inspector.open();inspector.waitForDebugger(); in it, it seems like it just freezes

  16. AriPerkkio commented on Nov 7, 2023

    @AriPerkkio

    Does this enable debugging a worker with chrome devtools?

    Yes, just save the code above into file and run with node. Here's picture from Chrome dev tools:

    image

  17. danieltroger commented on Nov 7, 2023

    @danieltroger

    Hmm, @AriPerkkio do you know if it works with require too? Just adding const inspector = require("node:inspector"); at the top of the worker I'm trying to debug, https://github.com/nodejs/node/blob/55d2eb53d78040472371eedd0e9e7922748dfb0e/lib/internal/modules/esm/worker.js makes the worker freeze for me (become unresponsive at 0% CPU usage) 😢

    And nothing shows up in chrome
    Screenshot 2023-11-07 at 19 47 19

    I'm trying to get a debugger to where this error is thrown, see reproduction steps there: swc-project/swc-node#736 (comment) and I'm following these steps to build node 20.9.0 https://www.devdungeon.com/content/build-nodejs-source

  18. connor4312 commented on Nov 7, 2023

    @connor4312
    Contributor

    Fyi, VS Code's JavaScript debugger automatically debugs node_workers using the NodeWorker domain (#26609 (comment)). So if you just need to debug a worker, easiest way is to run "Create JavaScript Debug Terminal" in VS Code; everything run in that terminal will be debugged.

  19. danieltroger commented on Nov 7, 2023

    @danieltroger

    @connor4312 TYSM, that got me a debugger inside of the worker!

    Unfortunately it doesn't seem like the vscode debugger can go to function definitions on all functions (
    [[FunctionLocation]]) and also the "break on caught exceptions" doesn't seem to work within a worker but I got further, thanks :)

  20. thoughtsunificator commented on Oct 26, 2024

    @thoughtsunificator

    But what about the CLI debugger?

    I'd like to be able to pass inspect as a positional argument to the worker causing it to start the CLI debugger just like we would do with node inspect script.js.

    As things are, I am unable to start the internal (CLI) debugger for a worker thread on Node v22.9.0 (Linux) with :

    node inspect-cli.js

    const { Worker, isMainThread } = require('node:worker_threads');
    if(isMainThread) {
    	const worker = new Worker(__filename, { execArgv: ["--inspect-brk"]   })
    	worker.on('error', console.error)
    	worker.on('exit', (code) => console.log(`Worker stopped with exit code ${code}`))
    } else {
    	debugger
    }

    What happens is, the process hangs, and here are the NODE_DEBUG and strace logs:

    node_debug.txt
    strace.txt

    Here's what the debugger yields when running the scripts command after attaching a debugger client using node inspect -p PID:

    Spoiler
    [user@pc node-playground]$ node inspect -p 123
    connecting to 127.0.0.1:9229 ... ok
    debug> scripts
      22: node:events
      24: node:buffer
      31: node:async_hooks
      32: node:timers
      34: node:path
      37: node:querystring
      42: node:fs
      47: node:util
      62: node:url
      66: node:diagnostics_channel
      75: inspect-cli.js
      76: node:worker_threads
      80: node:stream
      92: node:string_decoder
      95: node:stream/promises
      101: node:inspector
      102: node:tty
      103: node:net
    

    Finally, I think it would only make sense that nodejs start the CLI debugger:

    • As soon as it comes across a debugger
    • When an exception occurs if a given ENV is set accordingly
  21. cyans-nya commented on Jan 14, 2025

    @cyans-nya

    Can I use the Session from the node:inspector module and connect to a worker?

  22. eugeneo commented on Jan 14, 2025

    @eugeneo
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    inspectorIssues and PRs related to the V8 inspector protocol.workerIssues and PRs related to the worker_threads module and Worker API.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions