Debug netcore running in WSL with VS2017
Today I had to face the painful situation of a code in netcore that worked correctly in my machine (Windows 10) but that when running in Docker it failed miserably. I decided to dedicate this post to debug netcore running in WSL with VS2017.
Since the error that was printed by the console was that it could not find a file, the first thing was to verify that our code was cross-platform (eg that we always used Path.Combine and we did not concatenate the character \ to separate directories) since the Docker image was from Linux. Then we did all the verifications that were made and for having (permits, etc) and nothing. Everything seemed correct. In the end, we asked ourselves if it was a Docker problem or any Linux in general and we went to WSL.
We executed the program under WSL and we got the same error. That was good for two reasons: Docker was not the source of the error and also allowed us to debug the process.
There was but a problem: we had clarism that the error was NOT directly in our code , but that it was launched by an external library. Fortunately the library was from Microsoft (it was ML.NET 0.7) and that means we could use the power of “Source link” of VS2017 to debug the source code … without having it.
Enable Source Link
So, this was the first thing: enable Source Link. Summing up Source Link allows VS2017 to download the source code (from the libraries that support it, of course) automatically. It is nothing “new”, previous versions of VS already allowed it (under an option called “Source Server”), but Source Link solves many of the limitations that Source Server had. One of the advantages of Source Link is that one of its sources can be Github.
To enable Source Link you have to modify three settings of VS2017. The first is to allow debugging code that is not proper. To do this in Options-> Debugging-> General you must disable the “Enable Just My Code” option:
With this option enabled, VS2017 does not try to debug code other than our project (which is the usual, you do not usually want to debug a framework or external library).
The second option to modify is to enable “source link”. Again it’s in Options-> Debugging-> General
Enabling Source Link may suffice in the case of nugets that have embedded PDBs, but in many cases this is not the case. For these other cases we need to register a symbol server, from which VS2017 can download the symbols (PDBs) of the libraries that are loaded. Microsoft offers a symbol server. To enable it, just go to “Options-> Debugging-> Symbols” and check the box “Microsoft Symbol Servers”
With this we have VS2017 configured to debug external code, downloading the PDBs from the symbol server and the source code. We are ready.
Debug against WSL
Debugging against WSL is done through SSH. The only thing you should keep in mind is that you do not have a possible port conflict. Since WSL shares port space with Windows 10 itself, if you have an SSH server listening on Windows, port 22 will already have it occupied, so you must modify the SSH server port of the WSL. For me to work, I had to do the following:
- Uninstall the WSL server from WSL (sudo apt-get remove openssh-server)
- Reinstall (sudo apt-get install openssh-server).
- Edit the file / etc / ssh / sshd_config and put the entries (if any do not exist, you create it):
- Port to 2200 (or the value you prefer)
- UsePrivilegeSeperation to “no” (without the quotes)
- PasswordAuthentication to “yes” (without the quotes)
- Restart the ssh server (sudo service ssh -full-restart)
Those have been my steps until it has worked for me (without them VS2017 gave me error when connecting via SSH).
The next point was to execute the project in WSL (with dotnet run). My project was a Web Api and the error was given when I received a POST, so I could start it and then attach to the process with VS2017. To do this (with the sln loaded in VS), in Debug-> Attach To Process, select SSH and in “Connection Target” enter a descriptive name type “WSL”. That will launch the SSH connection dialog:
Enter the correct data (in Hostname is the name of your machine, Port the SSH port of WSL and of course “Username” and “Password” is your username and password of WSL).
Once this is done, VS2017 will connect to WSL (via SSH) and show you the processes. In my case, I had to mark “show process from all users” since the processes appeared under a user called “user +” (my WSL user is user). I do not know what that is, but it’s not a problem. You attach to a process and you can start debugging.
Now you must have a breakpoint placed in your source code, and once it stops, you can go using F11 to enter the methods. If you enter a method that is not yours (if not a framework or a library), VS2017 will download the source code and you can continue debugging.