Making your .NET language step correctly in the debugger
Firstly, I apologize for the length of this question. 

I am the author of IronScheme. Recently I have been working hard on emitting decent debug info, so that I can use the 'native' .NET debugger. 

While this has been partly successful, I am running into some teething problems.

The first problem is related to stepping.

Due to Scheme being an expression language, everything tends to be wrapped in parenthesis, unlike the major .NET languages which seems to be statement (or line) based.

The original code (Scheme) looks like:

    (define (baz x)
      (cond
        [(null? x) 
          x]
        [(pair? x) 
          (car x)]
        [else
          (assertion-violation #f "nooo" x)]))

I have on purpose laid out each expression on a newline.

The emitted code transforms to C# (via ILSpy) looks like:

    public static object ::baz(object x)
    {
      if (x == null)
      {
        return x;
      }
      if (x is Cons)
      {
        return Builtins.Car(x);
      }
      return #.ironscheme.exceptions::assertion-violation+(
         RuntimeHelpers.False, "nooo", Builtins.List(x));
    }

As you can see, pretty simple. 

Note: If the code was transformed into a conditional expression (?:) in C#, the whole thing would just be one debug step, keep that in mind.

Here is IL output with source and line numbers:

      .method public static object  '::baz'(object x) cil managed
      {
        // Code size       56 (0x38)
        .maxstack  6
        .line 15,15 : 1,2 ''
    //000014: 
    //000015: (define (baz x)
        IL_0000:  nop
        .line 17,17 : 6,15 ''
    //000016:   (cond
    //000017:     [(null? x) 
        IL_0001:  ldarg.0
        IL_0002:  brtrue     IL_0009
    
        .line 18,18 : 7,8 ''
    //000018:       x]
        IL_0007:  ldarg.0
        IL_0008:  ret
    
        .line 19,19 : 6,15 ''
    //000019:     [(pair? x) 
        .line 19,19 : 6,15 ''
        IL_0009:  ldarg.0
        IL_000a:  isinst [IronScheme]IronScheme.Runtime.Cons
        IL_000f:  ldnull
        IL_0010:  cgt.un
        IL_0012:  brfalse    IL_0020
    
        IL_0017:  ldarg.0
        .line 20,20 : 7,14 ''
    //000020:       (car x)]
        IL_0018:  tail.
        IL_001a:  call object [IronScheme]IronScheme.Runtime.Builtins::Car(object)
        IL_001f:  ret
    
        IL_0020:  ldsfld object 
             [Microsoft.Scripting]Microsoft.Scripting.RuntimeHelpers::False
        IL_0025:  ldstr      "nooo"
        IL_002a:  ldarg.0
        IL_002b:  call object [IronScheme]IronScheme.Runtime.Builtins::List(object)
        .line 22,22 : 7,40 ''
    //000021:     [else
    //000022:       (assertion-violation #f "nooo" x)]))
        IL_0030:  tail.
        IL_0032:  call object [ironscheme.boot]#::
           'ironscheme.exceptions::assertion-violation+'(object,object,object)
        IL_0037:  ret
      } // end of method 'eval-core(033)'::'::baz'

*Note:* To prevent the debugger from simply highlighting the entire method, I make the method entry point just 1 column wide.

As you can see, each expression maps correctly to a line.

Now the problem with stepping (tested on VS2010, but same/similar issue on VS2008):

These are with `IgnoreSymbolStoreSequencePoints` not applied.

1. Call baz with null arg, it works correctly. (null? x) followed by x.
2. Call baz with Cons arg, it works correctly. (null? x) then (pair? x) then (car x).
3. Call baz with other arg, it fails. (null? x) then (pair? x) then (car x) then (assertion-violation ...).

When applying `IgnoreSymbolStoreSequencePoints` (as recommended):

1. Call baz with null arg, it works correctly. (null? x) followed by x.
2. Call baz with Cons arg, it fails. (null? x) then (pair? x).
3. Call baz with other arg, it fails. (null? x) then (pair? x) then (car x) then (assertion-violation ...).

I also find in this mode that some lines (not shown here) are incorrectly highlighted, they are off by 1.

Here are some ideas what could be the causes:

- Tailcalls confuses the debugger
- Overlapping locations (not shown here) confuses the debugger (it does so very well when setting a breakpoint)
- ????

The second, but also serious, issue is the debugger failing to break/hit breakpoints in some cases.

The only place where I can get the debugger to break correctly (and consistantly), is at the method entry point. 

The situation gets a bit better when `IgnoreSymbolStoreSequencePoints` is not applied.


**Conclusion**

It might be that the VS debugger is just plain buggy  :(


**References:**

1. http://stackoverflow.com/questions/4357420/making-a-clr-net-language-debuggable
Making your .NET language step correctly in the debugger
===

Firstly, I apologize for the length of this question. 

I am the author of IronScheme. Recently I have been working hard on emitting decent debug info, so that I can use the 'native' .NET debugger. 

While this has been partly successful, I am running into some teething problems.

The first problem is related to stepping.

Due to Scheme being an expression language, everything tends to be wrapped in parenthesis, unlike the major .NET languages which seems to be statement (or line) based.

The original code (Scheme) looks like:

    (define (baz x)
      (cond
        [(null? x) 
          x]
        [(pair? x) 
          (car x)]
        [else
          (assertion-violation #f "nooo" x)]))

I have on purpose laid out each expression on a newline.

The emitted code transforms to C# (via ILSpy) looks like:

    public static object ::baz(object x)
    {
      if (x == null)
      {
        return x;
      }
      if (x is Cons)
      {
        return Builtins.Car(x);
      }
      return #.ironscheme.exceptions::assertion-violation+(
         RuntimeHelpers.False, "nooo", Builtins.List(x));
    }

As you can see, pretty simple. 

Note: If the code was transformed into a conditional expression (?:) in C#, the whole thing would just be one debug step, keep that in mind.

Here is IL output with source and line numbers:

      .method public static object  '::baz'(object x) cil managed
      {
        // Code size       56 (0x38)
        .maxstack  6
        .line 15,15 : 1,2 ''
    //000014: 
    //000015: (define (baz x)
        IL_0000:  nop
        .line 17,17 : 6,15 ''
    //000016:   (cond
    //000017:     [(null? x) 
        IL_0001:  ldarg.0
        IL_0002:  brtrue     IL_0009
    
        .line 18,18 : 7,8 ''
    //000018:       x]
        IL_0007:  ldarg.0
        IL_0008:  ret
    
        .line 19,19 : 6,15 ''
    //000019:     [(pair? x) 
        .line 19,19 : 6,15 ''
        IL_0009:  ldarg.0
        IL_000a:  isinst [IronScheme]IronScheme.Runtime.Cons
        IL_000f:  ldnull
        IL_0010:  cgt.un
        IL_0012:  brfalse    IL_0020
    
        IL_0017:  ldarg.0
        .line 20,20 : 7,14 ''
    //000020:       (car x)]
        IL_0018:  tail.
        IL_001a:  call object [IronScheme]IronScheme.Runtime.Builtins::Car(object)
        IL_001f:  ret
    
        IL_0020:  ldsfld object 
             [Microsoft.Scripting]Microsoft.Scripting.RuntimeHelpers::False
        IL_0025:  ldstr      "nooo"
        IL_002a:  ldarg.0
        IL_002b:  call object [IronScheme]IronScheme.Runtime.Builtins::List(object)
        .line 22,22 : 7,40 ''
    //000021:     [else
    //000022:       (assertion-violation #f "nooo" x)]))
        IL_0030:  tail.
        IL_0032:  call object [ironscheme.boot]#::
           'ironscheme.exceptions::assertion-violation+'(object,object,object)
        IL_0037:  ret
      } // end of method 'eval-core(033)'::'::baz'

*Note:* To prevent the debugger from simply highlighting the entire method, I make the method entry point just 1 column wide.

As you can see, each expression maps correctly to a line.

Now the problem with stepping (tested on VS2010, but same/similar issue on VS2008):

These are with `IgnoreSymbolStoreSequencePoints` not applied.

1. Call baz with null arg, it works correctly. (null? x) followed by x.
2. Call baz with Cons arg, it works correctly. (null? x) then (pair? x) then (car x).
3. Call baz with other arg, it fails. (null? x) then (pair? x) then (car x) then (assertion-violation ...).

When applying `IgnoreSymbolStoreSequencePoints` (as recommended):

1. Call baz with null arg, it works correctly. (null? x) followed by x.
2. Call baz with Cons arg, it fails. (null? x) then (pair? x).
3. Call baz with other arg, it fails. (null? x) then (pair? x) then (car x) then (assertion-violation ...).

I also find in this mode that some lines (not shown here) are incorrectly highlighted, they are off by 1.

Here are some ideas what could be the causes:

- Tailcalls confuses the debugger
- Overlapping locations (not shown here) confuses the debugger (it does so very well when setting a breakpoint)
- ????

The second, but also serious, issue is the debugger failing to break/hit breakpoints in some cases.

The only place where I can get the debugger to break correctly (and consistantly), is at the method entry point. 

The situation gets a bit better when `IgnoreSymbolStoreSequencePoints` is not applied.


**Conclusion**

It might be that the VS debugger is just plain buggy  :(


**References:**

1. http://stackoverflow.com/questions/4357420/making-a-clr-net-language-debuggable