Debugging .NET Core From VS2017 on Windows Subsystem for Linux

The new Microsoft is all about cross-platform and expanding the reach of .NET. In this post we will setup a local development environment Windows to debug against a .NET Core console application in the Windows Subsystem for linux.  Buckle up!

image

Windows Subsystem for Linux (WSL)

WSL is a new feature in Windows 10 which enables native Linux binaries to run on Windows.  For more info go to

https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/

To setup WSL you must first enable “Developer mode” in settings:

image

Next run “lxrun /install” from the console window and enter a root username and password when prompted.  You should see the following output:

— Beta feature —
This will install Ubuntu on Windows, distributed by Canonical
and licensed under its terms available here:
https://aka.ms/uowterms

Type “y” to continue: y
Downloading from the Windows Store… 100%
Extracting filesystem, this will take a few minutes…

Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username:

Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Installation successful!
The environment will start momentarily…
Documentation is available at:  https://aka.ms/wsldocs

Now you can run Bash on Ubuntu on Windows from the start menu:

image

image

Install .NET Core in WSL

Next you need to install .NET Core in WSL.  Microsoft provides a good install page but be you will need to alter the hosts files in Linux for the install scripts to run successfully.  Check out my earlier post this week for more details:

http://www.dotnetcatch.com/2017/04/19/dotnet-core-on-windows-10-subsystem-for-linux-error-sudo-unable-to-resolve-host/

Setup SSH in WSL

Visual Studio communicates with Linux over SSH.  The first thing you should know is Windows 10 has its own SSH proxy which uses port 22. WSL uses the same hostname as Windows so if you try to connect to your local host on port 22 (the default SSH port) it will actual try to connect to the SSH proxy in WIndows.  You may see two different errors in this situation.  If you are using your WSL username/password the authentication will fail:

image

Or if you pass your Windows creds you will see an “unknown” error:

image

Instead you will need to change the SSH configuration in WSL to use another port.  Use your preferred Linux editor to update the “/etc/ssh/sshd_config” file.

image

While you are there also set the UsePrivilegeSeperation setting to “no” and the PasswordAuthentication setting to “yes”.  I found these changes were necessary as well.  Save your changes and then restart the SSH service:

$ sudo service ssh –full-restart
* Stopping OpenBSD Secure Shell server sshd                             [ OK ]
* Starting OpenBSD Secure Shell server sshd                             [ OK ]
$ service ssh status
* sshd is running

Ideally, this should be all you need because WSL does have the SSH service by default  but in my case I found VS couldn’t connect to the default service setup.  It acted like it couldn’t find the SSH service on the host/port:

image

After some research I found a suggestion to remove and reinstall the SSH service which fixes the issue for me.

$ sudo apt-get remove openssh-server
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following packages were automatically installed and are no longer required:
  libfreetype6 os-prober
Use ‘apt-get autoremove’ to remove them.
The following packages will be REMOVED:
  openssh-server
0 upgraded, 0 newly installed, 1 to remove and 17 not upgraded.
After this operation, 955 kB disk space will be freed.
Do you want to continue? [Y/n] Y
(Reading database … 25762 files and directories currently installed.)
Removing openssh-server (1:6.6p1-2ubuntu2.8) …
initctl: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused
runlevel:/var/run/utmp: No such file or directory
invoke-rc.d: policy-rc.d denied execution of stop.
Processing triggers for man-db (2.6.7.1-1ubuntu1) …

$ sudo apt-get install openssh-server
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following packages were automatically installed and are no longer required:
  libfreetype6 os-prober
Use ‘apt-get autoremove’ to remove them.
Suggested packages:
  ssh-askpass rssh molly-guard monkeysphere
The following NEW packages will be installed:
  openssh-server
0 upgraded, 1 newly installed, 0 to remove and 17 not upgraded.
Need to get 0 B/322 kB of archives.
After this operation, 955 kB of additional disk space will be used.
Preconfiguring packages …
Selecting previously unselected package openssh-server.
(Reading database … 25749 files and directories currently installed.)
Preparing to unpack …/openssh-server_1%3a6.6p1-2ubuntu2.8_amd64.deb …
Unpacking openssh-server (1:6.6p1-2ubuntu2.8) …
Processing triggers for ufw (0.34~rc-0ubuntu2) …
Processing triggers for ureadahead (0.100.0-16) …
Processing triggers for man-db (2.6.7.1-1ubuntu1) …
Setting up openssh-server (1:6.6p1-2ubuntu2.8) …
initctl: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused
runlevel:/var/run/utmp: No such file or directory
invoke-rc.d: policy-rc.d denied execution of restart.

$ service ssh status
* sshd is running

This fixed it for me and VS2017 was then able to connect over SSH and list the process available:

image

Note you need to enable the Show processes from all users option.

Install Unzip

You also need to install the unzip app in your WSL bash so VS can install the VSDBG tool otherwise you will see the following error in the debug console when you attempt to attach to a dotnet process:

Starting unix command: ‘cd /home/rschiefer/.vs-debugger && chmod +x ./GetVsDbg.sh && ./GetVsDbg.sh -v vs2017u1 -l /home/rschiefer/.vs-debugger/vs2017u1 -d mi’
Info: Creating install directory
Using arguments
    Version                    : ‘vs2017u1’
    Location                   : ‘/home/rschiefer/.vs-debugger/vs2017u1’
    SkipDownloads              : ‘false’
    LaunchVsDbgAfter           : ‘true’
        VsDbgMode              : ‘mi’
    RemoveExistingOnUpgrade    : ‘false’
Info: Using vsdbg version ‘15.1.10310.1’
Info: Previous installation at /home/rschiefer/.vs-debugger/vs2017u1 not found
Info: Determining Runtime ID
Info: Using Runtime ID ‘ubuntu.14.04-x64’
Downloading https://vsdebugger.azureedge.net/vsdbg-15-1-10310-1/vsdbg-ubuntu.14.04-x64.zip
unzip command not found. Install unzip for this script to work.
cd /home/rschiefer/.vs-debugger && chmod +x ./GetVsDbg.sh && ./GetVsDbg.sh -v vs2017u1 -l /home/rschiefer/.vs-debugger/vs2017u1 -d mi exited with code 1.

Run the following command in your bash console to install unzip:

$ sudo apt-get install unzip
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following packages were automatically installed and are no longer required:
  libfreetype6 os-prober
Use ‘apt-get autoremove’ to remove them.
Suggested packages:
  zip
The following NEW packages will be installed:
  unzip
0 upgraded, 1 newly installed, 0 to remove and 17 not upgraded.
Need to get 157 kB of archives.
After this operation, 395 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ trusty-updates/main unzip amd64 6.0-9ubuntu1.5 [157 kB]
Fetched 157 kB in 5s (28.1 kB/s)
Selecting previously unselected package unzip.
(Reading database … 26708 files and directories currently installed.)
Preparing to unpack …/unzip_6.0-9ubuntu1.5_amd64.deb …
Unpacking unzip (6.0-9ubuntu1.5) …
Processing triggers for man-db (2.6.7.1-1ubuntu1) …
Processing triggers for mime-support (3.54ubuntu1.1) …
Setting up unzip (6.0-9ubuntu1.5) …

 

Debugging against WSL

Next we need to attach to our .NET Core application running in WSL.  Start by building your .NET Core app in Visual Studio.  Next traverse to the output directory for your project from the WSL bash console and run your app.  You will need some type of wait state in you app so you have time to attach to the process from VS.  I have a Console.ReadLine in my app that allows me to attach.

rschiefer@DESKTOP-12345:/mnt/c/Users/rschi/Documents/Visual Studio 2017/Projects/DebuggingDotNetCoreOnLinuxFromVS2017/DebuggingDotNetCoreOnLinuxFromVS2017/bin/Debug/netcoreapp1.1$ dotnet ./DebuggingDotNetCoreOnLinuxFromVS2017.dll
What is your name?

Once your app is running and ready to attach to, go back to VS and open the Attach to Process… windows from the Debug menu.  Select your dotnet process from the process list and click Attach:

image

Choose the Managed (.NET Core for Unix) code type:

image

Finally, we are attached and can debug the app:

image

Here is the source for my sample console app – https://github.com/rschiefer/DebuggingDotNetCoreOnLinuxFromVS2017

2017.04.26 – Update

It appears there may be a bug in debugging across SSH.  If you hit this please vote up the Connect issue.  For more details check out – 

AccessViolationException While Debugging over SSH

I hope this post was helpful to you.  If so or you have question/issues, please leave a comment below.

Happy debugging!

Leave a Reply