Advanced Debugging Techniques with Conditional Breakpoints in Visual Studio and C#

Advanced C# Debugging with Conditional Breakpoints
Debugging collections can be extremely difficult. Learn how to use conditional breakpoints and stop wearing your finger out hitting F5.

We’re all familiar with breakpoints, displayed as a red blob on the side of your Visual Studio editor.

A simple breakpoint - Ozcode

Breakpoints are places in the code where the debugger stops execution so you can poke around the state of the code and see what values variables are taking on. It is super useful to be able to see the state of execution when figuring out how code works or why it doesn’t work.

But what if the problem you’re trying to solve is deep inside a loop? Setting a breakpoint inside the loop will get you there but if the problem you’re solving is 500 items into a 10000 element collection you’re going to wear your fingers down pressing F5. Fortunately, conditional breakpoints make that easier.

Conditional Breakpoints

Conditional breakpoints allow setting conditions which dictate when the debugger will actually break and when it will skip over the breakpoint.

Setting a condition can take on a number of forms

  • Breaking when a variable takes on a specific value
  • Breaking when a variable changes
  • Breaking when a line of code has been hit a certain number of times
  • Breaking every n’th time through a loop

Let’s play with some conditional breakpoints.

Looping over data

First thing we need is some data to loop over. For random collections of data there is no better source than government-provided open data. I picked a random dataset from where I live in Canada. “Hexabromocyclododecane in Canadian Municipal Wastewater Treatment Systems” provides readings of whatever hexabromocyclododecane happens to be in the water system. I’m not sure exactly what hexabromocyclododecane is or if I want it but I do know that next time I play scrabble I’m going to use it and I’m going to win.

We’ll make use of the handy CsvHelper library to parse the CSV file (which I cleaned up a little bit manually before parsing).

using CsvHelper;
using System;
using System.IO;
namespace LargeDataLoop
{
    class Program
    {
        static void Main(string[] args)
        {
            using(var reader = new               StreamReader(@"HBCDBiosolids_EN_FR.csv"))
            using (var csv = new CsvReader(reader))
            {
                var records = csv.GetRecords();
                foreach (var record in records)
                    Console.WriteLine(record.CONCENTRATION_FOUND);
            }
        }
    }
}

This code does a great job of loading the file, looping over the records and printing out the concentrations.

Let’s introduce a bug and see how we can find it. Those concentrations take on values between 0 and 135. Let’s introduce a few records which have insane values. Now we can add a conditional breakpoint in the code to catch these

Sure enough, on the next pass through the loop, the debugger caught the large value.

You might also notice, in that screenshot, that I’ve turned on the heads up display to show the value for the field inline.

Ozcode also provides some handy shortcuts for setting conditional breakpoints. If we click through the magic wand icon then we get to a prepopulated conditional breakpoint dialog

This magic wand trick works even if you click into a collection and search for a specific value.

Set a conditional breakpoint with Ozcode
Enhance Visual Studio Debugging - Ozcode

Time Travel Debugging

Time travel debugging allows us to jump ahead and back in a collection and preview what the results will be. There is a similarly named feature in Visual Studio Enterprise but it works by recording a full session and letting you jump around in it. Ozcode’s version let’s you debug without ever executing the code.

To demo this, let’s update our code to do something a bit more exciting than printing out the concentrations of hexabromocyclododecane. We’d like to discard values which seem out to lunch. Statistics give us a pretty way to do that by calculating the standard deviation and discarding any values which exist outside of a specific z-score.

using (var reader = new StreamReader(@"HBCDBiosolids_EN_FR.csv"))
using (var csv = new CsvReader(reader))
{
     var records = csv.GetRecords<Record>().ToList();
     var mean = records.Sum(x => x.CONCENTRATION_FOUND) / records.Count();
     var standardDeviation = Math.Sqrt(records.Sum(x => Math.Pow(x.CONCENTRATION_FOUND - mean, 2) / records.Count()));
     var cleanRecords = new List();
     foreach (var record in records)
     {
         var zScore = Convert.ToDouble(record.CONCENTRATION_FOUND - mean) / standardDeviation;
         if (Math.Abs(zScore) > 2)
             Console.WriteLine($"{record.CONCENTRATION_FOUND} - {zScore}");
         else
             cleanRecords.Add(record);
     }
}

Here we calculate a z-score and discard anything outside of 2 deviations above and below the mean. Assuming normally distributed data, about 95% of the data should be within this range.

To see the power of forward time travel debugging, set a breakpoint on the loop line.

You can now click or scroll through the records and preview what the value for each of the entries in the collection will be. After choosing the iteration, the Heads up Display updates to show the value for the current iteration. You can hover over variables to see their values in the selected future iteration.

Need help finding just the right iteration to jump to? By clicking on Reveal (that’s the star) Ozcode will surface that part of the object so you can see it easily in the list of elements.

Ozcode provides some great tools for debugging large collections by allowing you to search for a particular problematic value and preview what’s going to happen. The collection debugging tools in Ozcode are my personal favorite feature and I’m sure you’ll love it too!


Ozcode Visual Studio Extension

Elevate LINQ debugging with visibility, clarity and insights into your queries.

Time travel to see how your code will execute before you step through it.

Heads-up display gives you powerful visualizations so you can instantly understand what’s happening in your code.

Data tips provide deep insights into your data letting you drill down to any level in a data object.

Ozcode Visual Studio Extension - Free Download

Simon Timms

Comments

Keep your code
in good shape!

Follow the latest news in the .NET debugging industry

Ready to Dive into Your Prod Code?

Easy debugging with full time-travel data

Share on facebook
Share on twitter

Recent Posts

Follow Us

Join OzCode YouTube Channel

Let’s start debugging, it’s free!

Keep your code in good shape!

Follow the latest news in the .NET debugging industry
Ozcode Logo

This website uses cookies to ensure you get the best experience on our website.