Posts tagged with debugging

8 Visual Studio debugging tips – debug like a boss

There are so many useful debugging features built into Visual Studio that aren’t well-known. Here are a few my favorites including some recent finds in VS 2013.

1. Breakpoint inside a lambda

If you click the left gutter to set breakpoints you could be easily mislead into thinking breakpoints happen at line level.

You can actually insert a breakpoint inside parts of the line such as inside a lambda in your LINQ expression. Just right-click the part of the code and choose Breakpoint > Insert breakpoint from the context menu.

2. Usable output window

Visual Studio output window filtering optionsThe output window is useful for debugging where breakpoints would be too invasive or interrupt flow but it’s pretty noisy.

Just right-click in the output window (make sure output is set to debug) and turn off the Module Load, Module Unload, Process Exit and Thread Exit to leave you with stuff you actually care about. Now Debug.WriteLine to your heart’s content.

You can also press CtrlS in the output window to save the contents.

3. Attach debugger to client and server (VS 2012)

It’s useful to have both server and client projects in a single solution so you only need one copy of Visual Studio running and don’t get lost alt-tabbing back and forth especially if they share common code such as a data model project.

One disadvantage is that the start-up project is the only one to get a debugger attached. If you encounter an exception it will show in your client not your server project.

That’s easily solved now. Right-click on the solution, choose properties and choose Multiple startup projects then select the Start action for the projects you need to attach to.

Visual Studio Solution properties dialog

4. Create a repro project template

If you’re responsible for a SDK or API create a simple application that uses your stuff in a small self-contained way. Then use File > Export template… to save it.

Now you can create a new project from your template whenever you need it with a few clicks. Even better make it available to users and testers so they can send you minimal repros.

5. Use the DebuggerDisplay attribute

By default the debugger will use ToString() for watch and auto windows which normally outputs class name. Even if you overrode ToString it’s probably not what somebody debugging wants to see at a glance.

Add DebuggerDisplay to your class with a simple expression to evaluate properties instead. e.g.:

[DebuggerDisplay("Order {ID,nq}")
class Order {
    public string ID { get { return id; } }
}

The “nq” prevents double-quotes from being emitted. You can also use methods here too but don’t do anything with subtle side-effects otherwise your observation of the subject will change its behavior and could cause weird issues.

6. Manage breakpoints

You set-up some interesting breakpoints and now you need to switch one-off for as it’s getting hit too much but you’ll need it again in a minute. If you remove the breakpoint you’ll have to come back and find it again.

Enter the much-overlooked Breakpoints window CtrlAltB. This will show all breakpoints you have set but crucially lets you disable them without unsetting them by simply removing the check-mark. Check it again to re-enable it.

Visual Studio breakpoints window

This window also provides the ability to quickly:

  • Condition when a breakpoint should occur
  • Hit count to see how often it is hit and to only break based on that count
  • Label a breakpoint to allow toggling on and off in batches
  • When Hit to put a message in the output window instead of actually breaking

7. Break on or output the caller information (.NET 4.5/Windows 8 Store)

There isn’t a global variable for the current method of the caller and getting the current stack can be a very slow operation.

One quick and simple trick is to add an extra optional string parameter to the method with the CallerMemberName attribute. e.g.

void MyFunction(string someValue, [CallerMemberName] string caller = null) {
    ...
}

Because it is an optional value you don’t need to modify any callers but you can now:

  1. Set a breakpoint condition inside DoSomething based on the caller variable
  2. Output the contents of caller to a log or output window

You can also use CallerLineNumber and CallerFilePath. Also remember that constructors, finalizers and operator overloads will display their underlying method names (.ctor, op_Equals etc).</a>

8. See the value returned by a function (VS 2013, .NET 4.5.1/Windows 8.1 Store)

Visual Studio autos windowSometimes you want to see what a function returned but you can’t easily because you didn’t store the value because it was the input to another function.

This was added in VS 2013 but is incredibly easy to miss as you have to be in the right place at the right time. The right place is the Autos window and the right time is exactly the step that returned you to where the function was called from. You won’t see this before you call the function or while in the function. It’s there for a single step and looks like this:

The arrow icon indicates it’s a return value and it lets you know the name of the function alongside it.

Wrap up

I also can’t stress enough how useful having logs are for troubleshooting once the software leaves your machine but that’s a much bigger discussion than this one.

Am I missing some great debugging tips? Feel free to let me know below :)

PS: Michael Parshin has some great tips on debugging too.

[)amien

LINQ to SQL log to debug window, file, memory or multiple writers

The Log property on a LINQ to SQL data context takes a TextWriter and streams out details of the SQL statements and parameters that are being generated and sent to the server.

Normally in examples you will see Console.Out being assigned to it which is fine for small demos and sandboxes but sooner or later you’ll want access to it in Windows or web applications. Here are some examples of how to redirect TextWriter output such as the DataContext log to other destinations.

Github has the latest version of ActionTextWriter etc.

To the output/debug window

The output/debug window mechanism actually uses a listener mechanism and so doesn’t actually directly expose a TextWriter interface however we can simply wrap up Debug.Write in something that does and use that instead:

class DebugTextWriter : System.IO.TextWriter {
   public override void Write(char[] buffer, int index, int count) {
       System.Diagnostics.Debug.Write(new String(buffer, index, count));
   }

   public override void Write(string value) {
       System.Diagnostics.Debug.Write(value);
   }

   public override Encoding Encoding {
       get { return System.Text.Encoding.Default; }
   }
}

To use it then simply:

myDataContext.Log = new DebugTextWriter();

To a file

#if DEBUG
 db.Log = new System.IO.StreamWriter("linq-to-sql.log") { AutoFlush = true };
#endif

If you wish to not overwrite the existing log file then change the constructor to include the parameter true after the filename. Bear in mind this log file can get very large and slow down your application with all that extra writing to disk and could well reveal information you’d rather wasn’t persisted there so the DEBUG conditional is recommended.

To memory

#if DEBUG
 var sw = new System.IO.StringWriter();
 db.Log = sw;
#endif

You will be able to examine sw or call ToString() on it to see the contents. Again this is not recommended for production as it will cause a lot of memory consumption as the StringWriter gets larger and larger.

To multiple writers

Here is a small useful class that lets you send the results intended for a TextWriter off into multiple writers.

class MulticastTextWriter : TextWriter {
  private readonly IList<TextWriter> textWriters;

  public MulticastTextWriter() : this(new List<TextWriter>()) {
  }

  public MulticastTextWriter(IList<TextWriter> textWriters) {
    this.textWriters = textWriters;
  }

  public void Add(TextWriter textWriter) {
    lock (textWriters)
      textWriters.Add(textWriter);
  }

  public bool Remove(TextWriter textWriter) {
    lock (textWriters)
      return textWriters.Remove(textWriter);
  }

  public override void Write(char[] buffer, int index, int count) {
    lock (textWriters)
      foreach (TextWriter textWriter in textWriters)
        textWriter.Write(buffer, index, count);
  }

  public override Encoding Encoding {
    get { return System.Text.Encoding.Default; }
  }
}

So if you wanted to output to a log and also to the debug window, you would use it like this (again recommended only for debugging):

var mw = new MulticastTextWriter();
mw.Add(new DebugTextWriter());
mw.Add(new System.IO.StreamWriter("linq-to-sql.log") { AutoFlush = true });
db.Log = mw;

Anything you want

To wrap things up here is a small TextWriter that lets you go off and do whatever you like with the string via the Action delegate.

class ActionTextWriter : TextWriter {
  private readonly Action<string> action;

  public ActionTextWriter(Action<string> action) {
    this.action = action;
  }

  public override void Write(char[] buffer, int index, int count) {
    Write(new string(buffer, index, count));
  }

  public override void Write(string value) {
    action.Invoke(value);
  }

  public override Encoding Encoding {
    get { return System.Text.Encoding.Default; }
  }
}

So if you wanted to output all log information to say a WinForms message box a tiny lambda expression gets you there:

db.Log = new ActionTextWriter(s => MessageBox.Show(s));

Have fun!

[)amien

Conditional operator bug in .NET 1.x & 2.0

I encountered a strange problem this week when a conditional operator appeared to be evaluating the false expression contrary to the C# documentation. The line looked like:

return (testObject == null ? null) : testObject.InstanceVariable;

The point of this line is to prevent accessing .InstanceVariable if the object is null and yet every time this line executed a NullReferenceException is thrown (and no I wasn’t overloading the == operator).

With a little experimentation I was able to narrow it down and produce a simple test case that exercised the bug on .NET 1.1 and .NET 2.0.

The problem is this: If the return parts are not of the same type and one of the members supports implicit conversion to the expect type, then it is called regardless of whether it is the the true part or not.

I filed the bug with Microsoft and it was confirmed last night by one of their C# engineers, there is a small chance it will be fixed in .NET 2.0 before release but we’ll have to see. I checked out some of the .NET classes and they too always access the object during an implicit conversion, however they are all value types which can not be null.

In the mean time there is an easy way to avoid this by modifying your implicit conversion methods to check for null before converting.

public static implicit operator string(ClassWithImplicitConversion objToConvert) {
    return objToConvert == null ? string.Empty : objToConvert.ToString();
}

A full test case appears below:

using System;

namespace ProveConditionalBug {
     class Program {
         static void Main(string[] args) {
             Console.Out.WriteLine("Testing... " + ProveConditional());
         }

        static string ProveConditional() {
            ClassHoldingImplicitConversionMember testObject = null;
            return (testObject == null) ? null : testObject.InstanceVariable;
        }
     }

    class ClassHoldingImplicitConversionMember {
        public ClassWithImplicitConversion InstanceVariable = null;<br />     }

    class ClassWithImplicitConversion {
         public string Value = "Test";
         public static implicit operator string(ClassWithImplicitConversion objToConvert) {
             return objToConvert.Value;
         }
     }
}

[)amien

Visual Studio 2003 – System.ArgumentException in debugger

I recently ran into a problem while debugging inside Visual Studio 2003.Net. Google couldn’t find me an answer, only a few other people with the same problem. Here’s my solution in the hope it might save somebody else some time.

Symptoms

Whenever debugging a specific VB.NET application that used a C# class library I would receive the following error certain objects in the C# class library:

<error: an exception of type: {System.ArgumentException} occurred>

Strangely only the ASP.NET application was affected, the WinForms application that also used this class library was unaffected. It also seemed to be localized to the debugger only, run-time behavior appeared to be just fine.

A reboot, rebuild project or a clear down of the ASP temp directory had no effect and another developer on the project had exactly the same problem despite the fact we do not share any binaries…

Solution

Close VS and delete all bin and obj directories from all projects in your solution if you want to be totally sure.

If you really don’t want to do this, deleting the .pdb’s from the project where the messed up object lives may be enough.

You may think forcing a rebuild with “rebuild solution” would achieve this, but it does not.

Cause (optional)

While debugging I noticed that I couldn’t create the messed up object interactively either. It was complaining that no constructor took 4 arguments and that it took 3. Well, it used to take 3 – over a week ago.

This leads me to believe that some combination of changing your C# source can make either VS or the C# compiler believe the debugging symbols are still up to date when they are not. This may possibly only affect VB.NET applications compiled against it.

It must be a reproducible bug because it happened on two different machines.

[)amien