I haven’t had a chance to post much recently, but I ran into a nice mail on an internal alias that listed the restrictions of set next statement.  Set next statement is a very powerful feature of the debugger that allows the IP (instruction pointer) to be moved.  It’s particularly useful when combined with Edit and Continue.  This feature can be accessed from the context menu of the editor when the debugger is active.  It may also be accessed by simply dragging the yellow arrow that appears on the left hand side of the screen while debugging.  There are a number of restrictions associated with changing the IP including:

  • It can only be set within the same function/method
  • There are restrictions around setting it into or out of a catch block (exception handler)
  • It must usually be moved to source lines
  • The IP cannot be set when the debugger is stopped at a first chance exception
  • The IP can only be set in the active frame (the frame that is actually executing).  That is, you cannot go 6 frames up the call stack and try to change the return address.

The most important thing to understand about this feature is that there is no real magic going on.  It does a very minimal amount of work to move the IP; it does not try to change values back to their previous state if the IP is moved higher up in a method.  If you’re tracking down a bug in your application, it’s often useful to step over most methods until something unexpected happens (e.g. a return value isn’t what you expect).  You can then use set next statement to re-run the method but this time step into it and examine what went wrong.  This can help track down bugs much faster, and of course, with Edit and Continue you can often fix the problem and then re-run the offending block of code to see if the change worked.

Imagine that you have this simple, somewhat useless bit of code:

using System;

 

class Example

{

    static void Main(string[] args)

    {

        int initialValue = 20;  

        initialValue++;

        Console.WriteLine(initialValue);

    }

}

Let’s suppose that you’re debugging this and your IP is located on Console.WriteLine:

IP

Now you right-click on the source line containing initialValue++ and select “Set Next Statement”:

IPSet

Finally you hit F5 to finish running the application.  The value written to the console is 22, not 21.  Again, this is because Set Next Statement doesn’t perform any kind of state analysis, it simply moves the IP to the location indicated.  In this case, it’s possible to get the original behavior by simply moving the IP up to the source line that sets the value of initialValue.  That’s trivial in this case since the initial assignment is immediately above the modification.  If there is a significant amount of code that you don’t want to re-run, then you can also modify the value in the locals/watch/etc. windows instead.