Debugging .NET core with SOS everywhere


Get some insight into debugging .NET code on non-Windows operating systems with this post from Premier Developer consultants Gustavo Varo and Ben Williams.


I have been working more and more with .NET Core and one question I keep getting from our customers and partners is about the debugging experience when using operating systems other than Windows. It is not a secret to anyone that Windows has an incredible debugging experience, whether you like to use Visual Studio or you like to script your debugging tasks using WinDbg.  But for everyone who is not using Windows, missing those tools is, in my opinion, one of the biggest sources of complaints when discussing the debugging experience.

With the introduction of .NET Core, the community got really excited with the possibility of running .NET code either on Linux or Mac, but how could we try to improve the debugging experience on those platforms? Today we will talk a little bit about how we can do that on Linux using the SOS debug extension. That’s correct, the SOS extension is now available on Linux as well.

What is the SOS extension?

The SOS extension is a debugging extension shipped with Windows that allows developers to debug managed code within WinDbg, CDB or NTSD

Remember that when you execute managed binaries, the runtime generates native code that is platform specific. The SOS extension allows you to debug that native code in a “managed way”.

How do I get started with SOS on Linux?

The very first step is to install a debugger. The debugger I will be using is called LLDB. LLDB is very similar to WinDbg and is also the debugger the SOS team has being using, so I have adopted it as my default debugger for Linux.

You can install LLDB from the follow link:

https://lldb.llvm.org/download.html

or you can also install it by running the following command:

sudo apt install lldb-3.5

Once you have lldb installed in your Linux machine, open the Terminal, go to lldb/Ubuntu/bin and launch the debugger by typing the following command on the prompt:

./lldb

Make sure the debugger was launched properly.

You will get the lldb prompt like the one below, if lldb was launched properly.

clip_image001

Create a .NET Core application… that crashes!

Now let’s create and run our console app on Linux, for that create a new folder and on the Terminal prompt type:

dotnet new
dotnet restore
dotnet run

The result of this operation should be something like this:

clip_image002

Let’s make our app a little bit more interesting. Open the Program.cs file and change your file like this:

clip_image003

Save the file and run the app again. Remember to press ENTER after you see the Hello World! message.

You should see something like this:

clip_image004

Now it is time to debug it!

Run the app again, but this time don’t press ENTER after you see the Hello World! message. Instead open a new Terminal window and get the process list in order to find the process id of the running app. You can do that by running the following command at the prompt:

ps -ejH

clip_image005

Once you find it, start the debugger and attach the process by entering the following command in lldb:

process attach -p [ProcessId]

clip_image006

Once attached, lldb should present the list of threads. You can also run use the bt command to retrieve the callstack of the current thread, however will be very hard to debug it since you can’t see the stack in a “managed way”

clip_image007

Load the SOS Extension

Loading the SOS extension will make things easier for us.

The first step is to find the extension, you can find it by running the following command:

find /usr/share/dotnet -name libsosplugin.so

clip_image008

Once you find the location we can load the extension with the follow command:

(lldb) plugin load /usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.1/libsosplugin.so

Alright the extension is loaded and now you can use the managed commands to debug your application.

To test that let’s run the clrstack command and now we get a much better view of what is going on.

clip_image009

We can also run other SOS commands like Threads to find out all the managed threads, to do that we type:

sos Threads

clip_image010

If you want to try out other SOS commands on your own, they are listed in the .NET Framework documentation

That’s it for now guys. Hope this can be useful for you!

Comments (0)

Skip to main content