emacs-lsp / dap-mode

Emacs :heart: Debug Adapter Protocol
https://emacs-lsp.github.io/dap-mode
GNU General Public License v3.0
1.29k stars 181 forks source link

Support for vscode-js-debug #369

Closed leungbk closed 10 months ago

leungbk commented 3 years ago

https://github.com/microsoft/vscode-js-debug

This ships with VSCode by default, but can also be installed via the Marketplace. It might be nice to have dap-mode working with this.

pretentious7 commented 3 years ago

This might be of interest.

MyriaCore commented 3 years ago

Bump! I've been searching everywhere for ways to do js debugging in emacs, and this appears to be it.

yyoncho commented 3 years ago

@MyriaCore you can use chrome/ff/node/edge debuggers currently available - you may follow https://emacs-lsp.github.io/lsp-mode/tutorials/reactjs-tutorial/

SimonAM commented 3 years ago

The installation instructions for node does not work for spacemacs. You have to C h-v to inspect the dap-node-debug-program before you are able to load templates or dap-node-setup

ghost commented 2 years ago

Seems like VSCode Node Debug is deprecated these days in favor of vscode-js-debug.

https://marketplace.visualstudio.com/items?itemName=ms-vscode.node-debug2

Important note: By default, this extension now delegates to the new js-debug extension which is built-in to VS Code. Please file issues on that repo. To revert to the old behavior, you can set "debug.javascript.usePreview": false in your settings.

Also some relevant discussions I found: https://github.com/mfussenegger/nvim-dap/issues/82 https://github.com/microsoft/vscode-js-debug/issues/902

mihaiolteanu commented 2 years ago

A bit off-topic, but would a different debugger support evaluating promises and callbacks while dap is stopped on a breakpoint?

Currently, if I am on a breakpoint and I want to dap-eval-region a setTimeout, for example, the callback does not get called,

console.log("Start testing");                     // <--- breakpoint here
setTimeout(() => console.log("timed out"), 1000); // <--- ...and evaluate this region; nothing gets printed on stdout

This is a simplified example, but I've seen this in both node and chrome, with both callbacks and promises. Though I'm still fresh with JavaScript, I assume the main stack is not empty while on a breakpoint, so the code in the callback queue does not get a chance to run?! I have seen that there are no such issues in indium, though, so I assume it is possible to evaluate whatever you want with dap, but I'm still searching how.

mihaiolteanu commented 2 years ago

See issue Eval async code while debugging(https://github.com/emacs-lsp/dap-mode/issues/553)

minikN commented 2 years ago

@yyoncho Hey, are there plans to integrate this since the other extensions are deprecated?

perrin4869 commented 2 years ago

node-debug2 doesn't even build anymore in nodejs@18 (uses gulp-typescript to build, and it doesn't work in node 18, see https://github.com/ivogabe/gulp-typescript/pull/670)

yyoncho commented 2 years ago

@yyoncho Hey, are there plans to integrate this since the other extensions are deprecated?

@minikN as soon as we have time but that is true for like 90% of the issues.

4lph4-Ph4un commented 2 years ago

Any light at the end of the tunnel? Could desperately use this!

eeshugerman commented 1 year ago

Reading through this thread (which OP @pretentious7 posted above) and you'll find that currently vscode-js-debug uses a relatively complicated mechanism to interface with VS Code, and this mechanism is not part of the DAP spec, nor is it documented.

So it's no wonder no one has stepped up to add support for vscode-js-debug in dap-mode yet.

The good news is this is changing: an addition to the DAP spec has been merged which vscode-js-debug can leverage in order to (1) move a lot of that complexity into its internals and (2) adhere to the spec, which should simplify adding support to non-VS Code clients. This work is tracked here: https://github.com/microsoft/vscode-js-debug/issues/1388.

So the outlook has brightened a bit, but dap-mode + vscode-js-debug is still a ways off.

@nbfalcon I suggest removing the good-first-issue label -- even once https://github.com/microsoft/vscode-js-debug/issues/1388 lands, this is still a complex/featureful server supporting multiple runtimes and using a brand new DAP request. It's also bad optics, given this is currently the most- :+1:'d dap-mode issue and has been open for years.

yyoncho commented 1 year ago

I will check if we can fix this now. The blocker on the server side is fixed.

yyoncho commented 1 year ago

Initial support is posted here: https://github.com/emacs-lsp/dap-mode/pull/733

For those who want to test: I have downloaded the version from here: https://github.com/microsoft/vscode-js-debug/issues/1388#issuecomment-1505547178 . Then you have to adjust dap-js-debug-program accordingly.

I have to decide whether we want/need the support for hierarchical debug sessions and I am not 100% sure what kind of use case they support.

eeshugerman commented 1 year ago

Sweet, thanks for tackling this! I'll try it out ASAP.

I have to decide whether we want/need the support for hierarchical debug sessions and I am not 100% sure what kind of use case they support.

By this you mean support for debugging spawned Node processes? IMO maybe the most compelling use case for this is integration tests. The app I work on these days runs on Node, as do its integration tests. The integration test code spawns a process for the app with child_process.spawn and then exercises its HTTP API. Using VS Code, I can set breakpoints in the app code and then run the integration tests with the debugger and hit those breakpoints! Super useful -- would love to be able to do this with dap-mode.

That said, I see no reason that this needs to be supported right off the bat. Just basic single-process functionality with vscode-js-debug would be a big step up over node-debug2.

yyoncho commented 1 year ago

By this you mean support for debugging spawned Node processes?

@eeshugerman I am not that familiar with nodejs but I think that we kind of support now this usecase.

Normally, one dap mode starts the adapter and connects to it. For that particular one, we start the adapter, and then the adapter sends us a message to start a new session against the same port. So, I guess if there is a debug config that will result in multiple new debug sessions(I. e. multiple children of the base debug session) this will work too.

eeshugerman commented 1 year ago

Ah cool! I'll try that out then, hopefully later today!

eeshugerman commented 1 year ago

Initial support is posted here: https://github.com/emacs-lsp/dap-mode/pull/733

For those who want to test: I have downloaded the version from here: https://github.com/microsoft/vscode-js-debug/issues/1388#issuecomment-1505547178 . Then you have to adjust dap-js-debug-program accordingly.

Just took this for a spin and it's looking good!

yyoncho commented 1 year ago

@eeshugerman good. I am looking for feedback for:

yyoncho commented 1 year ago

FWIW I added a method dap-js-setup and how you can install it using M-x dap-js-setup

Here it is also sample configuration that I am using for testing:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "pwa-node",
            "request": "launch",
            "name": "Demo",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${workspaceFolder}/server.js"
        }
    ]
}
eeshugerman commented 1 year ago

Good stuff! I'll stick with this for the next few days of work keeping those points in mind and get back to you with a more in-depth testing report.

jeff-phil commented 1 year ago

I just submitted PR #736 if interested in taking part or all of it. Was something I had started on a while back, and just got more time lately to work on it. Not trying to step on toes, missed other dap-js commit last week. ❤️

Tested and works great with pwa-node, pwa-chrome, and pwa-msedge debug types, and has seamless install from github releases.

Edit: while node-terminal is configured as debug type; I believe that is hardwired for vscode. But is a useful feature if can eventually be mimicked. However, pwa-node will do most needed things for debugging node apps.

Lastly, I did not update configuration.md, since I think there is a wider discussion of looking at removing some of the older (not working?) and redundant Javascript legacy adapters such: dap-chrome, dap-edge and dap-node and moving forward. And unfortunately, Firefox is not currently supported by vscode-js-debug.

Please let me know if have any questions or comments. Thanks!

eeshugerman commented 1 year ago

@yyoncho I've continued to run your branch over the past couple weeks and again overall it's working nicely, but

  • session management works fine(e. g. cleanup after child session exits is done)

I think there may be some issues here; I usually end up running list-processes and/or ibuffer after debugging to manually clean up a handful of buffers/processes each time. This may be user error though given:

  • UI makes sense - do we need to put the child session under the parent? Better naming for the child session?

Yes, putting the child under the parent in the sessions buffer would be a nice improvement. The names are fine as-is IMO.

Lastly I've run into issues with the output buffers getting in the way of each other. Each process gets its own output buffer (e.g. *bin.js out*, *mocha out*), but one is "pinned" to the bottom side window so I have to run purpose-toggle-window-buffer-dedicated to view the output of a different process in that window. Not sure what the best solution is here. Maybe direct all the streams to the parent process's output buffer? In my case at least that match what I see when I run the integration tests normally.

Konubinix commented 1 year ago

Hello. I don't know if that helps but this is my story.

I was trying to debug cucumber-js tests using launch.json content

        {
            "name": "Launch dev acceptance tests",
            "type": "node",
            "request": "launch",
            "program": "${workspaceRoot}/node_modules/.bin/cucumber-js",
            "cwd": "${workspaceRoot}/test",
            "args": ["--tags", "@only", "--parallel", "1"],
        },

And I got this error.

Debugger listening on ws://127.0.0.1:17936/1bc4fafd-85df-4402-8168-648062b75b13
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
Starting inspector on 127.0.0.1:17936 failed: address already in use

Trying to fix this, I came to realize that ms-vscode.node-debug2 is deprecated in favor of vscode-js-debug and found out this discussion to use it.

By looking at those discussion, I undertand that ms-vscode.node-debug2 is not that good with process spawning while vscode-js-debug does. Did I undertand correctly?

I tried #733 and it worked quite well.

The only issue I faced for now is that I could not run dap-debug-last, because the port of the old session gets used again along with a new port, leading to dap-mode asking the dap server to listen to one port and then tries to connect to another.

Now, there is also #736, that looks more comprehensive at first glance and also works quite well. It also does not work with dab-debug-last, because of another error dap-debug: (:request launch :name pwa-node-startDebugging<1> :__pendingTargetId a8fa65dba75c1d85b760e0f6 :outputCapture nil :skipFiles nil :timeout nil :host localhost :debugServer 38827 :debugPort 38827 :program .../node_modules/.bin/cucumber-js) does not specify :type

I don't understand what it means but I share it anyway, in case it helps.

I'm glad that I have something usable to debug my cucumber tests. Thank you :+1:

jeff-phil commented 1 year ago

Now, there is also #736, that looks more comprehensive at first glance and also works quite well.

I'm glad you tried it out and provided this feedback!

I notice in #736 on line 244 of dap-js-debug.el I had commented but left in passing the type to the spawned process. Sorry, I can't remember why I did that at the time... but I'd surmise there may have been an issue at the time in vscode-js-debug and I couldn't/shouldn't pass that. But now it's needed.

If you would try un-commenting that that line and retrying.

jeff-phil commented 1 year ago

@Konubinix Ignore my previous comment that I edited to strike out.

TLDR; I updated the PR #736 for the dap-debug-last command, if you want to resync and validate fixed for you.

I remembered why I had the type commented as previously mentioned. It was because the DAP specification states for the new StartDebugging reverse request the arguments ... must not contain any client-specific properties (e.g. type) .... I originally had type being set in the code, and commented to remind myself not to enable that. So that wasn't the problem.

Instead I realized that the child session was being added to the list of configurations, even though it cannot run by itself. The "last" debug configuration should be parent, not the child. I look for the child being last configuration, and remove it if there now.

I also re-synced the ~3 changes from upstream master, and reformatted a few long-lines.

Thank you again for trying it out and the feedback.

Konubinix commented 1 year ago

@jeff-phil : I confirm that I don't have the issue anymore.

ryanobjc commented 11 months ago

Hey,

Generally speaking this seems to work, I am running into a few issues:

Happy to debug more, I need a bit of help figuring out HOW to debug!

jeff-phil commented 11 months ago

@ryanobjc-

Excuse the clarifications on this (now 3 year) old thread. :)

Generally speaking this seems to work, I am running into a few issues:

Which, if any, PR are you using?

  • I can't always seem to print locals, or eval, I get "error in process filter: Wrong type argument: stringp, nil" ...
  • Sometimes the dap state gets 'weird' and I have a hard time restarting the debug.

Do you happen to have a simple test example to reproduce issues? And can you share your launch.json?

JordanAnthonyKing commented 1 month ago

Why was this closed when the PR is still open? I do notice there's a dap-js file in main but no documentation on it?