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

🚀 Feature Request: Breakpoint debugging support in workerd #371

Closed
dagnelies opened this issue Oct 3, 2022 · 39 comments
Closed

🚀 Feature Request: Breakpoint debugging support in workerd #371

dagnelies opened this issue Oct 3, 2022 · 39 comments
Labels
feature request Request for Workers team to add a feature

Comments

@dagnelies
Copy link

dagnelies commented Oct 3, 2022

Hi,

Basically, I don't know how to debug a worker with VS Code. When clicking "Run/Debug" in VS Code, it basically invokes what is configured in .vscode/launch.json. I just have no idea what should be written there since the dev environment is wrapped by wrangler.

Since most of the people are using VS Code and they probably have a similar problem, I assume it would be a nice addition and improving developer experience significantly.

I've also posted a related thread here: https://community.cloudflare.com/t/how-to-debug-use-breakpoints-with-vs-code/423775

Thanks for consideration.

@rozenmd
Copy link
Contributor

rozenmd commented Oct 3, 2022

@threepointone, didn't you manage to get this working with VS Code?

@threepointone
Copy link

https://twitter.com/threepointone/status/1525447479872868352

@JacobMGEvans JacobMGEvans self-assigned this Oct 3, 2022
@JacobMGEvans JacobMGEvans added the documentation Improvements or additions to documentation label Oct 3, 2022
@dagnelies
Copy link
Author

I tried it with the configuration given in the screenshot:

 {
    "type": "node",
    "request": "attach",
    "name": "Attach to remote",
    "address": "127.0.0.1",
    "port": 9229
}

...but in my case it did not work. I got a couple of issues.

Somehow the debugger has problems attaching. Sometimes it does, sometimes it does not.

A common error showing up in wrangler is:

X [ERROR] Tried to open a new devtools window when a previous one was already open.

While the debugger complains that its session has ended:

image

I managed to get one step ahead and get it briefly attached, just to see that the breakpoints still aren't working. This time the message looks as follows:

image

It suggested to add "sourceMap": true to the tsconfig.json, but even after this change it does not appear to work.

Back to "console.log" debugging 🤔

@willtemperley
Copy link

willtemperley commented Oct 18, 2022

Just ask VSCode to debug the wrangler cli.ts and it'll oblige, creating a launch.json in .vscode

Then add an "args" key to provide normal wrangler args, plus here I'm asking it to run a particular worker script.

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "program": "${workspaceFolder}/packages/wrangler/src/cli.ts",
      "outFiles": [
        "${workspaceFolder}/**/*.js"
      ],
      "args": ["dev", "/Users/you/worker/src/index.ts"]
    }
  ]
}

@dagnelies
Copy link
Author

Sorry for the late reply, but it did not work.

node.exe .\node_modules\wrangler\src\cli.ts dev --local --experimental-enable-local-persistence ./src/index.ts
(node:16444) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

After I added "type": "module" to wrangler/package.json directly, it not only broke the wrangler CLI itself, but debug lanch just triggers the next error:

node.exe .\node_modules\wrangler\src\cli.ts dev --local --experimental-enable-local-persistence ./src/index.ts
Uncaught TypeError TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for [...]\node_modules\wrangler\src\cli.ts

Running wrangler dev --local --experimental-enable-local-persistence src/index.ts works just fine though.

@chris-wickens
Copy link

chris-wickens commented Nov 26, 2022

@dagnelies can you share your launch.json if it's working? I have the same error.

Edit: Oh, you probably mean running wrangler devfrom the terminal is working. My bad.

I managed to get VS Code to launch the project, but breakpoints aren't working. It also doesn't have quite the same output in the debug console as running in terminal, e.g. it doesn't state the localhost address or port being listened on.

In package.json

{
  "name": "project-name",
  "description": "Description",
  "version": "1.0.0",
  "module": "./src/index.mjs",
  "private": true,
  "scripts": {
    "wrangler_dev": "wrangler dev"
  }
}

In launch.json

{
    "name": "wrangler (npm)",
    "type": "node",
    "request": "launch",
    "runtimeExecutable": "npm",
    "runtimeArgs": ["run", "wrangler_dev"], // same script name as in package.json
    "skipFiles": ["<node_internals>/**"]
}

@penalosa penalosa changed the title 🚀 Feature Request: Add a .vscode/launch.json during project creation 🚀 Feature Request: Breakpoint debugging support in workerd Feb 13, 2023
@penalosa
Copy link
Collaborator

Hi all! I've updated the title of this to reflect the internal work that's required here

@penalosa penalosa transferred this issue from cloudflare/workers-sdk Feb 13, 2023
@jasnell
Copy link
Member

jasnell commented Feb 14, 2023

Fundamentally everything that is needed for this is in place except for the fact that when a breakpoint is hit we have to be able to sleep the request thread. This implies that the dev protocol connection needs to be run on a separate thread. @kentonv probably has the most insight into how to make that work.

@kentonv
Copy link
Member

kentonv commented Feb 14, 2023

I am not sure, but I think we just need to set up a dedicated thread to run the inspector socket listen loop (in server.c++), thinking carefully about synchronization issues. Luckily the types in worker.h are already designed to allow multi-threaded access.

@JacobMGEvans JacobMGEvans removed their assignment Apr 3, 2023
@1000hz 1000hz added feature request Request for Workers team to add a feature documentation Improvements or additions to documentation and removed documentation Improvements or additions to documentation feature request Request for Workers team to add a feature labels Apr 10, 2023
@yacinehmito
Copy link

yacinehmito commented May 9, 2023

Seems related to this PR, but it has recently been closed without indications as to why: #595

@ohodson
Copy link
Contributor

ohodson commented May 9, 2023

Seems related to this PR, but it has recently been closed without indications as to why: #595

#595 is just enough to get breakpoints working locally, but this also intersects with product code and has some locking issues. It needs a better approach.

@ohodson ohodson added feature request Request for Workers team to add a feature and removed documentation Improvements or additions to documentation labels May 9, 2023
@yacinehmito
Copy link

Thank you very much for the prompt answer.

ohodson added a commit that referenced this issue May 26, 2023
This change place the InspectorService in a separate thread that
manages communication with over the websocket to the inspector.

A step towards supporting breakpoints for workerd.
ohodson added a commit that referenced this issue May 30, 2023
This change place the InspectorService in a separate thread that
manages communication with over the websocket to the inspector.

A step towards supporting breakpoints for workerd.
ohodson added a commit that referenced this issue Jun 5, 2023
This change place the InspectorService in a separate thread that
manages communication with over the websocket to the inspector.

A step towards supporting breakpoints for workerd.
ohodson added a commit that referenced this issue Jun 14, 2023
Supports breakpoints, debugger statements, stepping through code, live
edit when applicable. This largely comes for free by having a separate
thread for V8 inspector messages and implementing runMessageLoopOnPause.

Bug: #371
Bug: EW-7264
@tforster
Copy link

Do we have any update or ETA to enable debugging? My team really want to use Cloudflare Pages and Page Workers but without proper debugging I cannot possibly justify the additional time required to get to market.

ohodson added a commit that referenced this issue Aug 1, 2023
This change places the InspectorService in a separate thread that
manages communication with over the websocket to the inspector.

The change also adds support for runMessageLoopOnPause() and
quitMessageLoopOnPause() to support breakpoints and debugger
break statements.

There is also refactoring of the CDP message handling code so it can
be called with or without the isolate lock held.

This requires workerd to run with the command-line flag -i to turn
on inspector support.

This change only works for single service configurations. Support for
multi service configurations to follow.

To try this out using samples/helloworld as an example:

1) Edit "samples/helloworld/worker.js" and add a debugger statement
   to the handle(request) method.
2) Open workerd in VSCode, select 'workerd with inspector enabled (dbg)'
   as the Run and Debug Target panel. Hit F5 to run and select
   `samples/helloworld/config.capnp` as the config to use.
3) Open devtools in Chrome using either:
   * https://devtools.devprod.cloudflare.dev/js_app?ws=localhost:9229/main
   * chrome:://inspect
4) On the command-line run, `curl http://localhost:8080/`
5) Devtools should break into the running worker.

Bug: #371
Test: manual
Test: existing internal ew tests do not break
ohodson added a commit that referenced this issue Aug 1, 2023
This change places the InspectorService in a separate thread that
manages communication with over the websocket to the inspector.

The change also adds support for runMessageLoopOnPause() and
quitMessageLoopOnPause() to support breakpoints and debugger
break statements.

There is also refactoring of the CDP message handling code so it can
be called with or without the isolate lock held.

This requires workerd to run with the command-line flag -i to turn
on inspector support.

This change only works for single service configurations. Support for
multi service configurations to follow.

To try this out using samples/helloworld as an example:

1) Edit "samples/helloworld/worker.js" and add a debugger statement
   to the handle(request) method.
2) Open workerd in VSCode, select 'workerd with inspector enabled (dbg)'
   as the Run and Debug Target panel. Hit F5 to run and select
   `samples/helloworld/config.capnp` as the config to use.
3) Open devtools in Chrome using either:
   * https://devtools.devprod.cloudflare.dev/js_app?ws=localhost:9229/main
   * chrome:://inspect
4) On the command-line run, `curl http://localhost:8080/`
5) Devtools should break into the running worker.

Bug: #371
Test: manual
Test: existing internal ew tests do not break
@huw
Copy link

huw commented Aug 29, 2023

Here’s the current PR for Wrangler: cloudflare/workers-sdk#3774. It’ll require a Miniflare bump before it can land—but we’re on the home stretch now 🥹 (or if you use workerd directly I think things should work fine as-is, perhaps with some config to find your source maps?)

@abdolrhman
Copy link

I Need this for webstorm, how the old version support attach debugger and this does not,
using console is big waste of time, thanks for all effort

@huw
Copy link

huw commented Sep 6, 2023

We can close this issue, it shipped in Wrangler 3.7.0!

@ohodson
Copy link
Contributor

ohodson commented Sep 6, 2023

Thanks @huw, that's the last piece.

@ohodson ohodson closed this as completed Sep 6, 2023
@joseph-simpson
Copy link

joseph-simpson commented Sep 6, 2023

This is fantastic. Thanks for all the hard work!

I can set a breakpoint on the JS bundle generated by esbuild (it's something), but of course I really want to set my breakpoint on my TypeScript API (the dream).

I tried "sourceMap": true in my tsconfig.json (as per stackoverflow) but didn't see any source maps generated. Also, pages doesn't support wrangler.toml (wrangler pages --help suggests it does, but gives an error if you try).

Identifying the right process to attach to is also unclear (I use pnpm to run these in parallel: 1) esbuild src/index.ts --bundle --watch --format=esm --outfile=dist/_worker.js 2) wrangler pages dev dist --live-reload)

After looking through the existing issues, I was going to raise a new issue requesting a short explanation for "How to breakpoint debugging on TypeScript code running under pages locally", but I couldn't see a fit with any of the available categories...

Does anyone have any suggestions on how to achieve this or how to raise the requirement?

Thanks again!

(Sorry for such a long comment)

@mrbbot
Copy link
Contributor

mrbbot commented Sep 6, 2023

Hey @joseph-simpson! 👋 Try adding --sourcemap to your esbuild command, and opening the DevTools by pressing d in your wrangler pages dev session. That seemed to work for me on [email protected]. 🙂

@tforster
Copy link

tforster commented Sep 6, 2023

@mrbbot What exactly is d supposed to do? I get that it says "open Devtools" but it has never done anything for me. I just assumed it was an uncompleted placeholder for something.

Is there a sample .vscode/launch.json config that can be shared so that we can get debugging working properly in VSCode now?

@mrbbot
Copy link
Contributor

mrbbot commented Sep 7, 2023

Hey @tforster! 👋 d should open https://devtools.devprod.cloudflare.dev/js_app?theme=systemPreferred&debugger=true&ws=localhost%3A9229%2Fcore:user:<YOUR_WORKER_NAME> in a supported browser. I'm guessing you don't have Chrome installed? Firefox should be supported too, but I'm aware of an issue that prevents Wrangler from opening it.

Breakpoint debugging is currently supported using these DevTools, or WebStorm's. I've struggled to get VSCode's debugger working. 😕 VSCode's attach configurations connect to workerd, but can't find source maps. From reading VSCode docs, it looks like VSCode ignores //# sourceMappingURL comments, and instead looks for source maps itself on disk? I may be misunderstanding this though. wrangler dev stores its source maps in a random temporary directory that VSCode wouldn't be able to find on its own. I've got some ideas to try work around this though. Will report back on this thread if I get something working. 👍

@huw
Copy link

huw commented Sep 7, 2023

The --no-bundle flag should work in the meantime, yeah? I’ll give it a try soon and report back if you’re not sure

@mrbbot
Copy link
Contributor

mrbbot commented Sep 8, 2023

Put a PR up to add support for VSCode's debugger to Miniflare: cloudflare/miniflare#681. We'll need to make a few Wrangler changes too, but these should be done soon. 🙂

@tforster
Copy link

tforster commented Sep 8, 2023

@mrbbot

...I'm guessing you don't have Chrome installed?

Actually, I do. However, I am running Wrangler in Ubuntu 22.04 under WSL2 on Windows. So Wrangler is on the Ubuntu side but my Chrome is on Windows. I had no idea that "d" was supposed to open Chrome Dev Tools. But now I do I have been able to open it manually. Do you happen to know where the code is that launches Chrome from the "d" keypress (e.g. what repo? Maybe even where in the repo?) If you can point me in that direction I can take a look and perhaps figure out how to get it to work in WSL2 world.

Breakpoint debugging is currently supported using these DevTools, or WebStorm's. I've struggled to get VSCode's debugger working. 😕 VSCode's attach configurations connect to workerd, but can't find source maps. From reading VSCode docs, it looks like VSCode ignores //# sourceMappingURL comments, and instead looks for source maps itself on disk? I may be misunderstanding this though. wrangler dev stores its source maps in a random temporary directory that VSCode wouldn't be able to find on its own. I've got some ideas to try work around this though. Will report back on this thread if I get something working. 👍

Breakpoint debugging is something I have taken for granted since I first experienced it with Turbo Pascal on DOS back in the late 80's. So much so that I never stopped to think about how it works. From day 1 JavaScript debugging in VSCode just worked out of the box. And, the Serverless Framework has the serverless-offline plugin making debugging AWS Lambda's a breeze too. CloudFlare workers are the first time I have come across the inability to debug in many years. So, it's really good to understand the intricacies and challenges of the process. I am going to read the VSCode docs you linked so I have a better appreciation and understanding.

Thanks for all your work on this!!!

@mrbbot
Copy link
Contributor

mrbbot commented Sep 8, 2023

@tforster

Do you happen to know where the code is that launches Chrome from the "d" keypress?

https://github.com/cloudflare/workers-sdk/blob/a986f19f2d7989639524f9fd73761ea69aef4f6b/packages/wrangler/src/inspect.ts#L853-L900

Thanks for offering to take a look! 😃

@ben-xD
Copy link

ben-xD commented Sep 17, 2023

When using webstorm's debugger, the worker freezes and all subsequent requests will time out. The devtools debugger works fine.

@ohodson
Copy link
Contributor

ohodson commented Sep 19, 2023

@ben-xD can you open a new ticket and post repro instructions for the issue in WebStorm and/or capture a Chrome Debugger Protocol trace in WebStorm? Thanks

@Phoenixmatrix
Copy link

Phoenixmatrix commented Sep 24, 2023

Just tried wrangler 3.9 which I believe has these changes. Unfortunately it doesn't seem to be quite there yet.

The problem from what I see is that the sourcemap generated for the bundle by wrangler's toolchain doesn't follow along from previous files correctly. Eg: right now if I run the app with VSCode's debugger, it correctly maps the bundle (under "deployed" in the devtools) to the compiled file my tooling is generating, but if sourcemaps were processed correctly, it should map all the way to the original files:

image

You can see in the screenshot that the bundle (ick3smw8et.js) maps correctly to [[path]].js. But the later is itself a bundle. This is a remix app, and it has sourcemaps for //# sourceMappingURL=/build/[[path]].js.map, and that isn't honored (my knowledge of sourcemap building is limited, but I believe the previous sourcemap in the chain is supposed to be provided when building the next one, so you only need the final one. Maybe that's not happening?)

The issue happens both in Visual Studio Code, or at the Cloudflare devtool url.

If I copy paste the [[path]].js.map in my public directory, and in the devtool rightclick in ick3smw8et.js, choose add sourcemaps, and add a url to [[path]].js.map, then I can debug my source correctly. With the asterisk that its' missing extra lines added during the bundling process, so all my breakpoints are 2-3 lines off.

Considering mapping from my own bundler's output, to wrangler's bundler output, seems to be working correctly, I have a feeling if the final sourcemap was generated using the previous sourcemaps, this would "Just work".

Sorry for the very convoluted explanation! I know just enough about the topic to be dangerous.

Update: Yeah, I can confirm thats (at least part of) the issue. If I look at the sourcemap directly (the one generated in tmp), it has the info, but not the file mapping all the way back. Even if I load it manually in the devtools, all I get is the functions directory files showing up in the devtool, but loading my own sourcemaps, it behaves correctly.

You can reproduce in a more isolated environment by pasting the sourcemap in this visualizer (note I had to remove the sourcemap url from the sourcemap for it to work). Then you'll see in the dropdown that only the intermediate files are available, not the original source (eg: typescript). I can't find in the esbuild documentation how to ensure that multiple chained sourcemap transformations apply correctly, so I can't suggest a solution.

@BrandonNoad
Copy link

@Phoenixmatrix It looks like the sourceMappingURL was just fixed by remix-run/remix#7574

With that change, I am able to get the breakpoint debugging working with the Chrome Dev Tools. Though, if you are using Remix, remix dev -c swallows the [b] open a browser, [d] open Devtools, [c] clear console, [x] to exit menu, so you need to open https://devtools.devprod.cloudflare.dev/js_app?theme=systemPreferred&ws=localhost%3A9229%2Fws&debugger=true manually.

I wasn't able to get debugging working inside VS Code though.

@mrbbot
Copy link
Contributor

mrbbot commented Oct 2, 2023

@BrandonNoad, are you on macOS? cloudflare/workers-sdk#4067 will likely need to be released before this works in VSCode (hopefully going out tomorrow) 👍

@BrandonNoad
Copy link

@BrandonNoad, are you on macOS? cloudflare/workers-sdk#4067 will likely need to be released before this works in VSCode (hopefully going out tomorrow) 👍

Yes, I'm on a Mac. I'll keep an eye out for the release. Thanks for fixing!

@mrbbot
Copy link
Contributor

mrbbot commented Oct 6, 2023

[email protected] was released yesterday including this fix. I don't think the Remix fix has been released yet, but this should get us one step closer. 👍

@BrandonNoad
Copy link

[email protected] was released yesterday including this fix. I don't think the Remix fix has been released yet, but this should get us one step closer. 👍

Awesome. I verified that it works as expected with both patches applied. Thanks for fixing it!

@JustinGrote
Copy link

My notes for getting vscode working and operating with the vitest vscode test runner extension are here:
cloudflare/workers-sdk#4174

@swyxio
Copy link

swyxio commented Feb 3, 2024

saving people some time from reading thru a bunch of the above - the vscode + wrangler instructions you need are here. https://blog.cloudflare.com/debugging-cloudflare-workers#breakpoints

@ReinsBrain
Copy link

ReinsBrain commented May 5, 2024

I just noticed that I can get DevTools working (but not vscode debugging) in windows following instructions at: https://blog.cloudflare.com/debugging-cloudflare-workers#breakpoints

...but DevTools still won't work in WSL2 - anybody else have that problem and workaround?
(ps. using Typescript)

@erik-beus
Copy link

I just noticed that I can get DevTools working (but not vscode debugging) in windows following instructions at: https://blog.cloudflare.com/debugging-cloudflare-workers#breakpoints

...but DevTools still won't work in WSL2 - anybody else have that problem and workaround? (ps. using Typescript)

I'm not a Windows user, but I also had issues attaching my debugger. For me, downgrading wrangler fixed it - see reported issue here cloudflare/workers-sdk#5297

@pendevx
Copy link

pendevx commented May 26, 2024

On one of my projects, I couldn't get either chrome devtools nor vscode to work, no matter what, where on the other, vscode breakpoints were working but devtools wouldn't until vscode's debugger session was started then closed, but even in that case the devtools just showed a bunch of random eval-somehash.js files

Honestly could just be some configuration reason with my first project, idk what though, and it's really annoying to keep having to use console.log debugging ngl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Request for Workers team to add a feature
Projects
None yet
Development

No branches or pull requests