Debugging 3rd Party Nuget Packages

The following is a braindump of what options there are for debugging Nuget packages not maintained by you. It’s not particulary polished, but maybe it’ll help someone.

So you need two things to step-through code:

  1. The souce code, and…
  2. The .pdb file that was built alongside the .dll you want to debug

1. Loading the Source Code

You need to tell Visual Studio how to locate the source code for the files you want to debug. There are a few options here:

How do I find the source code for a given Nuget package?

Unfortunately, there is no standard way for a Nuget package or metadata on the Nuget site that points from the package to the corresponding source code.

What usally works for me is to go to the Nuget page for the package and click on Project Site. With luck, the site exists and has a link somewhere on it to Github or wherever the source code lives.

Failing that, I usually pick a class name I know exists in the package and search Google for DerpComponent.cs or search Github directly for the class name. With luck, the class name is fairly unique and the source code has been indexed by one of the search engines.

Note: there is not a 1-1 relationship between Nuget packages and source code repositories. One repo may contain the source code for many Nuget packages. This can make it hard to know if you’re looking at the right repo when the code you want is buried 5 folders deep alongside a bunch of other stuff.

What if I don’t have the source code?

Untested: Try using dotPeek’s Symbol Server feature

How do I set a breakpoint on library code that hasn’t been added to the solution?

Untested—I haven’t actually gotten this to work but it seems like it might work.

  1. Open the Breakpoints window (DebugWindowsBreakpoints)
  2. Click on NewFunction Breakpoint
  3. Enter the full Namespace.Class.Method name of the function you want the debugger to break on
  4. Cross your fingers

2. Loading the Symbols (.pdb) File

In order to debug a .dll file, you must have the corresponding .pdb file from the exact same build. Visual Studio correlates the two files using a combination of the file name and a matching GUID stored in the .dll and .pdb file that gets regenerated for each build. (Source)

There are a few ways to get a usable .pdb file. Each option is explained below.

2a. Nuget Symbols Package

When publishing a Nuget package, the author has the option to additionally publish a symbol package, which contains the corresponding .pdb file.

To tell Visual Studio to automatically load .pdb files in symbol packages I think you have to do one of 2 things (and I’m not sure which one it actually is):

You may have noticed I don’t really know how to do this, and that’s because I find so few packages publish symbols (correctly?) that this has never worked for me.

How do if I know if the Nuget package I want to debug publishes a symbol package?

You don’t :( At least, I don’t think there’s an easy way to know. You can take a look at the project site and maybe it will say something if it publishes symbols?

2b. Load the .pdb files manually

Perhaps you were able to download the .pdb files from the website or something. Perhaps the .pdb files are available on a file-share put there by the build server. However it happened, you have access to the .pdb files. Great.

  1. Start debugging your application in Visual Studio
  2. Open the Modules window (DebugWindowsModules)
  3. Find the .dll you want to debug (it helps to sort by Name)
  4. Right click on the .dll and select Load Symbols
  5. Browse to the directory containing the corresponding .pdb file

Note: You can enter network paths (for example: \\buildserver1\c$\builds\whatever\) in the file window, so you don’t have to copy the .pdb files to your local machine.

You should now be able to set breakpoints and have them be hit.

2c. Create the .pdb files yourself

What if you can’t find the .pdb file for the .dll file you want to debug? Or what if you don’t have the exact right version of it? You’re kind of out of luck, but there is one option…

You have access to the source code, right? So build the .dll yourself, then you’ll have the right .pdb file for it.

Figuring out how to build random codebases is outside the scope of this document. You’ll have to figure that out for yourself.

Once you’ve built the .dll, you now need to update your app to load the .dll you built (instead of the version that Visual Studio downloaded from Nuget). I’ve done this two different ways the old way, and the new way.

Old Way

Old versions of Nuget create a packages folder in the root of your solution where it downloads and unzips Nuget packages. If you find the corresponding Nuget package folder, you can overwrite the Nuget .dll files with the ones you built. When you build your app the .dll files you dropped in there should be copied into the output directory of your app.

New Way

New versions of Nuget don’t create a packages folder anywhere as far as I can tell.

That leaves only two other ways I know how to override the .dll:

  1. Manually copy your .dll into the output directory everytime you build the solution
  2. Manually remove the Nuget references from the project and replace it with a hardcoded reference (Solution ExplorerDependenciesAdd ReferenceBrowse)

You may run into a few different issues doing #2:

However you do it, once you get the app running so that it references the re-built .dll, you should be able to debug by following the directions in 2a.

See Also