How To Debug A .NET Core Nuget Package?
Nuget is a package manager for .NET. It provides tools to create and reference packages. The Nuget official packages repository is nuget.org.
Each Nuget package contains .NET binaries that will be referenced by the project where you install the package.
The CLI that comes with the .NET Core development tools provides a command to easily create a Nuget package from your sources (you can also use the same CLI to build, run, publish and package your .NET Core project and more! For more information please take a look to the official .NET Core CLI documentation).
Thus, it is easier than ever to take your code industrialization to the next level by packaging your reusable code and reference it across your projects. Doing this can save you a lot of time but it also has a disadvantage: as the code base of your Nuget packages grows, the list of bugs as well. As a consequence, it is very important to be able to debug a Nuget package in the specific context of a bug.
Let's see how to do that, Symbols will be our friends :)
A symbol is a file containing metadata that represent the link between your original source code and the machine code that has been translated by a compiler.
In the Microsoft world, a symbol is represented by a .PDB (Program DataBase) file. It is the heart of the debugging process because thanks to these metadata, the debugging tools are able to correlate the instructions executing in the application to the original source code and providing features like breakpoint or variable watchers.
Publish a .NET Core Nuget package with symbols
The .NET Core CLI comes with a dedicated command to create a Nuget Package: pack. This command accepts arguments to include the source files as well as the generated symbols to the package:
dotnet pack [PROJECT].csproj --include-symbols --include-source
This command creates 2 different versions of the same package:
- [PACKAGE].nupkg is the primary package including binaries and other files described by the project or the .nuspec configuration file.
- [PACKAGE].symbols.nupkg is the symbol package including the same elements + sources and symbols
You can then push both primary and symbol packages at the same time using the following command line:
dotnet nuget push [PACKAGE].nupkg
Your package is now ready to be debugged by other developpers ;)
Debug a Nuget Package
Let's see now how to debug a referenced Nuget package with Visual Studio and the symbolsource.org symbol server. It is pretty simple, you just have to follow the Recommended configuration on symbolsource.com, I put it here for consistency with the post:
- Go to Tools -> Options -> Debugger -> General.
- Uncheck “Enable Just My Code (Managed only)”.
- Uncheck “Enable .NET Framework source stepping”. Yes, it is misleading, but if you don't, then Visual Studio will ignore your custom server order (see further on).
- Check “Enable source server support”.
- Uncheck “Require source files to exactly match the original version”
- Go to Tools -> Options -> Debugger -> Symbols.
- Select a folder for the local symbol/source cache.
- Add symbol servers under “Symbol file (.pdb) locations”. Pay attention to the correct order, because some servers may contain symbols for the same binaries: with or without sources. We recommend the following setup:
Your debug sessions will be then significantly slower to run, especially the first time. Indeed, Visual Studio will download the available symbols of each loaded dependency which will make your Nuget package debuggable. The symbols will be put in a cache making the next debug sessions warmup faster.
That being said, you would better create a dedicated Visual Studio setting configuration to activate/deactivate symbols debugging configuration (for more information on Visual Studio customized settings, read this).
Enjoy your new debugging capabilities!