Awesome debugger behavior in VB.net

A colleague discovered wired debugger behavior in his VB.net solution. I admit that this will be more of an academic question, since it only affects the sequence of statements highlighted during debugging, and not the general behavior of the code. So everyone is curious:

We divided this into the following minimal console application:

Private Sub PlayWithExceptions
    Dim a = 2
    Try
        throw new Exception("1")
    Catch ex As Exception
        If a = 2 Then
            Dim x = New XElement("Dummy")
        Else
            throw
        End If
    End Try
End Sub

Sub Main()
    Try
        PlayWithExceptions()
    Catch ex As Exception
    End Try
End Sub

As you can see, the debugger throws an Exception ("1"), and the debugger goes into the catch clause of the PlayWithExceptions method. There, as "a" is always 2, the debugger goes to some dummy code (New XElement ...), from there to "End If" and, finally, back to the Else-list in the throw statement , I admit that Visual Studio does not throw an exception, but, nevertheless, it looks very strange.

" a = 2" "If True" .

.

Private Sub PlayWithExceptions
    Dim a = 2
    Try
        throw new Exception("1")
    Catch ex As Exception When a = 2
        Dim x = New XElement("Dummy")
    Catch ex As Exception
        throw
    End Try
End sub

# .

private static void PlayWithExceptions()
{
    var a = 2;
    try
    {
        throw new Exception("1");
    }
    catch (Exception)
    {
        if (a == 2)
        {
            var x = new XElement("Dummy");
        }
        else
        {
            throw;
        }
    }
}

static void Main(string[] args)
{
    try
    {
        PlayWithExceptions();
    }
    catch (Exception ex)
    {
    }
}

.Net3.5 .Net4.6, AnyCPU x86 - VB-. Debug . VS2015 3.

- , Visual Studio VB ( )? ...

+4
1

, / VB.Net Err, "" .

IL rethrow , , . , , - , , , () .

Err, Throw, , . . . IL_0035 :

.method private static void  PlayWithExceptions() cil managed
{
  // Code size       62 (0x3e)
  .maxstack  2
  .locals init ([0] int32 a,
           [1] class [mscorlib]System.Exception ex,
           [2] bool V_2,
           [3] class [System.Xml.Linq]System.Xml.Linq.XElement x)
  IL_0000:  nop
  IL_0001:  ldc.i4.2
  IL_0002:  stloc.0
  .try
  {
    IL_0003:  nop
    IL_0004:  ldstr      "1"
    IL_0009:  newobj     instance void [mscorlib]System.Exception::.ctor(string)
    IL_000e:  throw
  }  // end .try
  catch [mscorlib]System.Exception 
  {
    IL_000f:  dup
    IL_0010:  call       void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)
    IL_0015:  stloc.1
    IL_0016:  nop
    IL_0017:  ldloc.0
    IL_0018:  ldc.i4.2
    IL_0019:  ceq
    IL_001b:  stloc.2
    IL_001c:  ldloc.2
    IL_001d:  brfalse.s  IL_0032
    IL_001f:  ldstr      "Dummy"
    IL_0024:  call       class [System.Xml.Linq]System.Xml.Linq.XName [System.Xml.Linq]System.Xml.Linq.XName::op_Implicit(string)
    IL_0029:  newobj     instance void [System.Xml.Linq]System.Xml.Linq.XElement::.ctor(class [System.Xml.Linq]System.Xml.Linq.XName)
    IL_002e:  stloc.3
    IL_002f:  nop
    IL_0030:  br.s       IL_0035
    IL_0032:  nop
    IL_0033:  rethrow
//Debugger is pausing at IL_0035 when the highlight is on Throw
    IL_0035:  call       void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
    IL_003a:  leave.s    IL_003c
  }  // end handler
  IL_003c:  nop
  IL_003d:  ret
} // end of method Module1::PlayWithExceptions

If True Throw, , , , . Catch SetProjectError/ClearProjectError, , Throw, New XElement.

+5

Source: https://habr.com/ru/post/1658091/


All Articles