When it comes to debugging software, tools are extremely important. Get the right tool and you extract the right information. Get the right information and you can find the root cause of the problem. Find the root cause and you’ve fixed the bug.

You are about to see a biased list of what I believe to be the most essential tools for investigating problems in C # .NET. These will help you find and resolve the root cause of any difficult problem.

In addition to common problems in code, the following tools handle a variety of problem types, including:

  • Performance issues
  • Memory problems (GC pressure and memory leaks)
  • Problems with third-party libraries,
  • Production issues
  • Problems with the network

 

1. Visual Studio

Our main debugging tool is Visual Studio. It is one of the best IDEs in the world and not just in the .NET space. It has a ton of features to help you debug, including various tool windows, exceptional options, tooltips, and much more. Microsoft has managed to integrate basic and advanced functionality into a fairly intuitive program, making Visual Studio the second most popular IDE for all developers according to the 2019 StackOverflow survey.

In recent years, two competitors have appeared to challenge the .NET IDE spot: Rider and Visual Studio Code. In my experience, the two are still way behind Visual Studio in debugging capabilities. Although the functionality and refactoring performance of Rider is very impressive.

Besides interactive (traditional) debugging, VS includes a lot of other analysis tools:

  • Performance profiling
  • Memory profiling
  • Historical debugging with IntelliTrace
  • Cloud Debugger (as part of Cloud Explorer)

I prefer to use other tools for all of the above categories. Read on, they are on the list.

 

2. dnSpy

dnSpy is one of the most useful tools for .NET debugging. It is a good decompiler, but its main use is as a debugger. dnSpy allows you to debug any .NET assembly, regardless of symbols or source code.

This tool looks like Visual Studio. When you start debugging a .NET process without symbols or source code, dnSpy shows you the decompiled code. Now here’s the magic: you can place breakpoints in the decompiled code itself. When these breakpoints hit, you’ll see local variables, threads, a stack of calls, and get a full debugging experience. This makes dnSpy my favorite tool for debugging third-party code and debugging a production environment.

It is light and requires no installation. Just copy the file to any production machine and start debugging.

 

3. dotPeek

  1. dotPeek is a free .NET decompiler from JetBrains. A bunch of their tools have made their way through this list. I prefer dotPeek to other decompilers like ILSpy or JustDecompile for two reasons:
  2. dotPeek provides a better user experience. Or at least one that I feel more comfortable with. It looks and feels like ReSharper, so that could be the reason.
    dotPeek can create a symbol server from any assembly, even without symbols or source code. It’s a bit like dnSpy this way – it decompiles code and creates symbols from it. With dotPeek, Visual Studio can debug any third-party code, just like dnSpy. To see how exactly, check out my article: Debugging third-party .NET code without symbols in Visual Studio.

 

4. dotTrace

dotTrace is another great tool from JetBrains. It’s my favorite performance profiler. dotTrace allows you to “record” an application run, and then analyze the performance of the recording. You will be able to see the time spent in each of the methods called, the time spent by database calls, by HTTP requests, during garbage collection, etc.

dotTrace
The image above shows a short recording analysis of Visual Studio. You can see that ShowWindow took 155 milliseconds, which includes the HwndSourceHook (42ms), Convert (16ms) methods, etc. Execution of this method includes 42% WPF calls, 20% user code, 12% GC Wait, 10% Collections code, 10% reflection and 5% system code. Pretty good, right?

It’s a bit of a learning curve at first, but once you get used to it, it becomes very intuitive.

 

5. SciTech .NET memory profiler

Another category of essential tools for solving memory problems is a memory profiler. These can be memory leaks or performance effects caused by GC (GC Pressure). If you have a large enough application, sooner or later you will experience memory problems. Hope later for you because these types of problems can be devastating.

A memory profiler can take a “memory snapshot” and allow you to examine it. You will see which objects take up the most memory, who references them and why they were not retrieved. By comparing two snapshots, you can find memory leaks.

Several memory profilers are available, but SciTech’s .NET memory profiler is my favorite. I found it to be the most powerful and had the fewest problems.

 

6. OzCode

OzCode is a unique extension of Visual Studio. Its sole purpose is to assist with your interactive debugging in Visual Studio. OzCode has a large group of features, which can be classified into 4 parts:

  • Head-up display – OzCode adds useful visualization features when debugging. This includes red / green highlighting and showing the selected properties of an object: image-20200130110830384
    There are other things, like breaking down an expression into its parts: image-20200130110914124
  • LINQ Debugging – LINQ is excellent when writing code, but very difficult to debug. OzCode allows you to study LINQ expressions when debugging in an almost perfect case.
  • Debug OzCode LINQ
    To learn more about debugging LINQ with or without OzCode, see my article: How to debug LINQ queries in C #.
  • DataTip – The DataTip is the popup window you get when hovering over variables in Visual Studio. OzCode replaces this window with its own much better DataTip. It allows “favorite” properties, search, export in JSON format and other functionalities.
  • Time travel – OzCode 4 has added a revolutionary new debugging feature. It can predict the future without moving the breakpoint. In other words, you will be able to see what is happening in a line of code that occurs after your current debugging position. However, this feature does not work in all cases. For example, OzCode cannot predict things like the results of HTTP requests or SQL requests because it has to execute them for that.

 

7. SysInternals Suite

Sysinternals is a suite of utilities to troubleshoot and monitor Windows software. It includes some of the most important tools we need for debugging. I suggest downloading the entire suite and saving somewhere easily typed from the command line, like C:\Sysinternals. There are dozens of tools, some more useful than others. Let’s list a few of the most important ones for .NET:
Process Explorer
Process Explorer is like the Windows Task Manager on steroids. It has a myriad of features useful for debugging. Here are some of them:

  • View loaded modules
  • View handles
  • Create Dumps
  • View process tree
  • View performance counters

 

Process Monitor
Process Monitor, also known as ProcMon, allows you to monitor processes activity events. Specifically, you can see Registry events, File events, Network events, Thread activity, and Profiling events. If you want to find out which files or registry values your process touched, then ProcMon is the tool to help you.
ProcDump
ProcDump is a command-line tool for saving dump files. It can generate dumps immediately or on triggers. For example, creating a dump on a crash or a hang. It’s my recommended tool of choice for capturing dumps. Here are some of its abilities:

  • Create a Dump immediately
  • Create several dumps with specific intervals (like 3 dumps, 5 seconds apart)
  • Create dump once a CPU threshold has passed
  • Create dump if a process is hanged
  • Create dump on crash

To find out more about ProcDump and Dumps, see my article: How to Create, Use, and Debug .NET application Crash Dumps in 2019.

 

8. Performance Monitor (PerfMon)

There’s a built-in mechanism in Windows called Performance Counters. These counters allow you to follow a whole lot of useful metrics on what’s happening on the machine. Those might be system-wide metrics or for a specific process. Here are some examples of things you can measure with performance counters:

  • CPU Usage
  • Memory Usage
  • Number of exceptions thrown in a process
  • I/O Bytes read/written
  • Number of requests to your ASP.NET application
  • Request response time in your ASP.NET application

There are probably thousands of different counters you can monitor and they come as specific as possible. For example, if you want to find out about Memory Usage of a process, there are counters for: Private Bytes, Virtual Bytes, Working Set, Working Set – Private, Gen X Collections, % Time in GC, Large Object Heap Size, and many more.
Performance Monitor is the tool that allows you to visualize these counters (although there are other tools as well). It’s pre-installed with any Windows installation. To run it, just type “Performance Monitor” in your start menu or type perfmon in command prompt.

9. PerfView

PerfView is an open-source general-purpose analysis tool. It has a ton of things it can do, here are some of them:

  • Performance Profiling
  • Memory Profiling
  • Analyze ETW events
  • Import performance snapshots from Linux
  • Various reports on application behavior, including JIT Compilation times, Garbage collection times, and others

Its analysis is based on Event Tracing for Windows (ETW) events. This is a built-in logging system that’s extremely fast and used by every part of Windows. Everything logs events to ETW, including the Kernel, Windows OS, the CLR runtime, IIS, ASP.NET framework, WPF, and more.

PerfView is easily the most complicated tool on this list. But it’s also very powerful. To get started with PerfView, I suggest watching Vance Morrison’s video lessons series on Channel 9.

 

10. Fiddler

Fiddler a free tool by Progress Telerik. It’s one of my favorite tools to debug network calls. It’s defined as an HTTP proxy server and it’s just that. It captures all HTTP requests, logs the data, and sends the request on its way.
For each request, you can see the process, headers, payload, response, status. Well, everything.

For debugging, Fiddler has a couple of useful features:

  • Replay requests – You can right-click any request and click “Replay”, which will send the exact same request again. It’s useful when debugging server-side problems. If you want to reproduce a problematic request, Fiddler saves you the trouble of re-running the scenario on the client to send the same request again. It also helps with requests that are hard to reproduce.
  • Edit & Replay requests – Besides just replaying requests, Fiddler allows us to modify them. You can change the headers, body, and even the URL itself. You can use it to see how your server-side deals with edge cases. Or to reproduces a problem that happens on a specific request.

The one that wasn’t mentioned
You might wonder about some of the tools I didn’t mention. If you’ve been around long enough, you might think of WinDbg. If you’re not familiar with it, WinDbg is a command-line debugger that used to be the main debugging tool for Windows. Kind of like Visual Studio is now for .NET. I feel it’s not that relevant now in 2020 and going forward. At least not for .NET development. You can do almost everything with Visual Studio and it’s going to be easier and faster.

Some things are still better with WinDbg. Like its scripting capabilities, easy remoting, and convenient production debugging. You can copy WinDbg to a production machine and investigate dump files pretty quickly. It doesn’t require a big installation like Visual Studio. But I always find myself copying dump files to my development machine and opening them with a memory profiler or Visual Studio. It’s just more effective. So my verdict is that WinDbg is not an essential debugging tool for .NET development anymore.

Leave A Comment

Whatsapp Whatsapp Skype