Vscode: Using WSL - How to use Bash for the launch configurations?

Created on 19 Apr 2017  路  36Comments  路  Source: microsoft/vscode

  • VSCode Version: 1.11.2
  • OS Version: Windows 10 (Version 1703), with WSL enabled.

I asked the question on StackOverflow, but without any answers, so I guess it's maybe not possible...

I use Visual Studio Code to develop a TypeScript Node application on Windows 10, with WSL enabled.

Thanks to other threads, I'm almost able to run a VSCode task with Bash on Ubuntu on Windows.

But now I try to do the same with a launch configuration. How can I make a launch configuration to use the node executable installed in WSL instead of the one installed on Windows?

If I run this command directly in the integrated terminal, with Bash, it works :

node src/start.js

But when I press "[F5]" and start a launch configuration that runs this same file, I get an error : "Error: %1 is not a valid Win32 application". This is because the oracledb library is used and has been compiled in Bash, not in Windows.

How can I make a launch configuration use Bash to run Node?

WSL debug feature-request on-testplan

Most helpful comment

Would very much love to see this supported. With WSL having such great support for for 3rd party applications and how much better suited linux is for web dev, I'd much prefer to develop with it as my underlying environment.

All 36 comments

You should be able to set bash as shell or use bash.exe -c node (or probably C:\Windows\sysnative\bash.exe -c node) as node launch path but you will then run into https://github.com/Microsoft/vscode/issues/24072 I think

@CherryDT I'm not sure I understand what you suggest. Am I wrong or a launch configuration always uses node as the main program, so I can't make it use bash.exe. For example, this doesn't work in launch.json :

{
    "version": "2.0.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "test",
            "program": "C:\\Windows\\sysnative\\bash.exe",
            "args": [
                "-c",
                "node",
                "${workspaceRoot}/src/start.js"
            ],
            "cwd": "${workspaceRoot}",
            "outFiles": [],
            "sourceMaps": true,
            "internalConsoleOptions": "openOnSessionStart",
            "timeout": 20000
        }
    ]
}

I may not understand correctly, but I think this kind of launch configuration will run something like :

node C:\Windows\sysnative\bash.exe -c node ${workspaceRoot}/src/start.js

and of course the first "node" makes no sense. Please correct me if I'm wrong!

It uses the configured runtimeExecutable which _defaults_ to node if not set. So, you need to set it not in program, but in runtimeExecutable.

But as I said, this will still not work due to path issues (https://github.com/Microsoft/vscode/issues/24072) because even if you hardcode the workspaceRoot to a WSL path so the WSL node can actually understand it, you will get issues with debugging because VSCode will not recognize the WSL path it gets from node when node talks about current files, and will open a read-only view with the file content at the WSL path, which breaks breakpoints (which have been set at the corresponding Windows-path-version of the same file).

@CherryDT I try to reach the point where you are so I can ask this issue to be closed and follow yours!
Setting runtimeExecutable seems to be the way to go, indeed, thanks! But then, even without using ${workspaceRoot}, I'm still unable to make a simple example work. For example :

{
    "version": "2.0.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "test",
            "runtimeExecutable": "C:\\Windows\\sysnative\\bash.exe",
            "runtimeArgs": [
                "-c",
                "pwd"
            ],
            "outFiles": [],
            "sourceMaps": true,
            "internalConsoleOptions": "openOnSessionStart",
            "timeout": 20000
        }
    ]
}

This results in : "/bin/bash: --debug-brk=37360: invalid option ...".

Do you have a sample of a working launch configuration usingbash.exe, without the need of an intermediate .bat file?

@electrotype Can't test it right now, I remember I originally used a batch file but I did so in order to convert the path from Windows to WSL.

I would try to include -c node in the runtimeExecutable already, but I don't know if this works the way I think it does. Did you try that?

No luck sadly...

"runtimeExecutable": "C:\\Windows\\sysnative\\bash.exe -c pwd",
=>
_Error - Attribute 'runtimeExecutable' does not exist ('C:\Windows\sysnative\bash.exe -c pwd')._

and

"runtimeExecutable": "\"C:\\Windows\\sysnative\\bash.exe\" -c pwd",
=>
_Error - Cannot launch debug target (spawn "C:\Windows\sysnative\bash.exe" -c pwd ENOENT).._

I see. Then you probably need a batch file, but I'm not sure if this even works (because you can't CreateProcess a batch file I think), maybe you need a custom EXE.

I was now able to find the old files and see how I did it back then (before I opened https://github.com/Microsoft/vscode/issues/11681) - I had a more complex approach there because I tried to also convert paths, and environment variables for things like NODE_ENV (this was before Anniversary Update by the way). This worked but then I ran into the issue with the paths with VSCode debugging.

What I did back then was to build an executable on the Windows side which translates paths and environment variables and base64 encodes them to avoid escaping issues, then starts bash.exe with a custom shell script which decodes everything again and finally launches node.

FreeBasic source code of the Windows-side program: https://gist.github.com/CherryDT/0045624611834c888c24797df2844386

WSL-side shell script:
https://gist.github.com/CherryDT/44788497e8870121969b840892d99025

Nice hacking!

I'm not sure I'm ready to go this way though... VSCode should make this way, way much easier.

I'll stick to the regular cmd shell for now...

As mentioned, this doesn't lead to anywhere anyways because of the path issues. However, according to https://github.com/Microsoft/vscode/issues/24072 and similar issues, it is possible to get WSL node to launch by setting the terminal shell (terminal.integrated.shell.window, I believe) to bash - but I don't observe this behavior, so I'm not exactly sure what is going on there.

My current workflow is much less hackish than what I tried there before: I just have bash as terminal shell and run node --inspect --debug-brk from there manually, and I use VSCode to _attach_ to it (instead of launching it). The downside is that I have to set remoteRoot manually to the WSL path of the project root which is problematic if the launch.json is to be checked into a repository (because of paths which are different for individual developers).

@isidorn assigning to you. It is about launch configs not tasks.

Assigning to @weinand to check if he has ideas. Otherwise stack overflow is the best route for questions like this.

I'm only speculating here but you could try this:

  • configure VS Code's integrated (or external) terminal to use WSL (I assume this is possible but I've never tried this myself).
  • setup your launch config so that it launches the debug target in either the integrated or the external terminal (use IntelliSense to find the possible values):
    js { "type": "node", "request": "launch", "name": "Launch Program", "program": "${workspaceRoot}/app.js", "console": "integratedTerminal" }

With this VS Code will launch "node" in the integrated terminal and I assume that it will use the WSL "node".

@weinand You are right, integratedTerminal does work, in that sense that it does use the correct node executable!

For the records, both "externalTerminal" and "internalConsole" fail though :

"externalTerminal" :

"internalConsole" :

That said, "integratedTerminal" only works when the entry file is at the very root. For example, a ${workspaceRoot}/src/start.js entry file (instead of ${workspaceRoot}/test.js) fails :

But I think I've seen there already are existing issues about those missing slashes?

@electrotype I was also trying to use integratedTerminal option and got this.
screenshot 160

I guess when bash changes directory (check second highlighted box ) all the slashes are missing (check first highlighted box ). Issue definitely is because of missing slashes.

Currently VS Code launch configurations do not support WSL. The code is not aware of WSL and just assumes Windows which results in paths with backslashes.

@DhirajAdPushup your problem is #24072

I have scoured the internet and as far as I can tell you cannot debug VSCode using WSL / bash as the executing environment. For now I'm going to switch back using chrome dev tools built in debugger via the --inspect flag. I am a big +1 on getting this integration working, it feels like VSCode is so close being that you can run the terminal with bash, and almost launch a program using bash, just not debug it. But maybe I'm missing something.

You can, you just can't launch it. Launch it manually with --inspect or --inspect --debug-brk, then attach to it using VSCode. Set the remoteRoot in your attach launch config to the WSL path of your project, then also the breakpoints will work properly.

@CherryDT Thanks! I'll try that.

@ryanstevens If that works then do share the process and experience here, that will be a great help.

Would very much love to see this supported. With WSL having such great support for for 3rd party applications and how much better suited linux is for web dev, I'd much prefer to develop with it as my underlying environment.

I tried to launch my Node app with the --inspect flag in WSL, and Attach the VSCode debugger to it, but my breakpoints do not works, VSCode tells me that there is a sourcemap problem.

What do I need to do to make my breakpoints work ?

@sylvainlap as I mentioned above, set the remoteRoot in your attach launch config to the WSL path of your project in order to make breakpoints work.

@CherryDT that doesn't work. Say my WSL project path is /mnt/c/Users/abc/project1, but when I open files in VS code their path is C:\Users\abc\project1, so setting break points still won't work.

@Alkasai : Why? That's exactly what the remoteRoot is for. You tell VSCode that your "remote server" (in this case WSL) uses the root path /mnt/c/Users/abc/project1 so it knows how to translate the path. It's the same thing when you are debugging on an actual remote server via SSH tunnels for example.

Example configuration I use:

{
    "name": "Attach to Process",
    "type": "node",
    "protocol": "inspector",
    "request": "attach",
    "port": 9229,
    "localRoot": "${workspaceRoot}",
    "remoteRoot": "/mnt/c/Users/david/proj/my-project"
}

Then I can launch my project in WSL using node --inspect-brk server.js for example and attach from VSCode. Everything works fine this way.

I proposed a while ago that remoteRoot should also work for "launch" actions and not only "attach", I believe the issue has been closed as resolved but I have to admin that I didn't test it yet, I am still using my attach method. So it can be that you can actually use "request": "launch" and launch it from VSCode, if you can tell it to use WSL node...

Ah thank you it finally works! I wasn't sure what the format was remoteRoot and I think I was missing localRoot.
Also tried "request": "launch" and it seems it still doesn't work. I mean the breakpoints work, but it doesn't know know how to translate a path like /src/..... So whenever it tries to interpret this kind of path it fails.

Status update:

Today VS Code node debugging knows nothing about "WSL" but since it supports "remote debugging", the WSL case is already supported nicely when launching the target manually in WSL and then using an "attach" configuration (see @CherryDT's config from above).

For the WSL "launch" case we've received https://github.com/Microsoft/vscode-node-debug/pull/156 and https://github.com/Microsoft/vscode-node-debug2/pull/126 that add the required functionality to the node debugger.

Edit: Nevermind, my remoteRoot has changed and I didn't pay attention... silly me.

@CherryDT not sure if you can help. Your solution used to work for me for a while. I also had "sourceMaps": true in there.

{
    "name": "Attach to Process",
    "type": "node",
    "protocol": "inspector",
    "request": "attach",
    "port": 9229,
    "localRoot": "${workspaceRoot}",
    "remoteRoot": "/mnt/c/Users/david/proj/my-project",
        "sourceMaps": true
}

But since I switch to a new machine, the break points stopped working for me. It still attaches the debugger and breaks on the entry, just like it used to. But all breakpoint now show as 'Breakpoints set but not yet bound'.

Hi all. Note that node debugging support in WSL is in the way soon!

@bitcrazed - That's awesome! What are the specific things your team has had to do to facilitate this? ie: What barriers would I be hitting right now if I tried?

In the October release VS Code supports the useWSL flag for both the "legacy" and the "inspector" protocol of node.js.

@weinand - You should make that useWsl.

@atrauzzi no, the name of the flag is useWSL.

This is mostly in passing, but the only reason the flag in your comments jumped out at me is because most communities have settled on lower case letters for everything after the first when applying pascal case to acronyms: https://stackoverflow.com/questions/15526107/acronyms-in-camelcase (one of probably many references available) - I'd be interested in seeing anything that indicates otherwise.

As VS Code really aims for the community, this seems like a natural choice to follow conventions at large.

@atrauzzi thanks for the references. Now I understand.
However, since the name 'useWSL' shipped in September, we will not change the spelling in October because that would break launch configs.

It would be worthwhile to see this as an overall suggestion. Not just for the current flag in question here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

borekb picture borekb  路  3Comments

philipgiuliani picture philipgiuliani  路  3Comments

lukehoban picture lukehoban  路  3Comments

biij5698 picture biij5698  路  3Comments

mrkiley picture mrkiley  路  3Comments