Fody/MethodTimer

Expression-bodied member causes System.InvalidProgramException: JIT Compiler encountered an internal limitation.

Drachenkaetzchen opened this issue · 4 comments

Describe the issue

When using an expression-bodied member, the IL generated is invalid and causes either one of these two exceptions: ´System.InvalidProgramException: JIT Compiler encountered an internal limitation.or aSystem.InvalidProgramException: Common Language Runtime detected an invalid program.`

  • Fody.4.0.2 as well as Fody v4.2.1
  • MethodTimer.Fody.2.3.2
  • Not sure which .NET Core SDK Rider uses, but it uses the v15 toolset which is part of Visual Studio 2017.
  • CLR v4.0.30319

Note/Use Case: I'm not keen on having MethodTimer on properties, but I wanted to use [assembly: Time] without going through 100s of Methods and adding the [Time] attribute manually. My use case is to accumulate the overall execution time per method, including the number of times it gets called to figure out optimization potential.

Minimal Repro

Create a new, empty solution and add a new console application to it. Add [assembly: Time] to AssemblyInfo.cs

using System.Diagnostics;

namespace ConsoleApplication1
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            var foo = new Foo() {Bar = new Bar()};
            Debug.WriteLine(foo.FooBar); // System.InvalidProgramException
            Debug.WriteLine(foo.FooBar2); // Works
            Debug.WriteLine(foo.FooBar3); // Works
        }
        
        public class Foo
        {
            public bool FooBar => Bar != null && Bar.Foobar;
            public bool FooBar2 => Bar != null;
            
            public bool FooBar3
            {
                get { return Bar != null && Bar.Foobar; }
            }

            public Bar Bar
            {
                get;set;
           
            }
        }

        public class Bar
        {
            public bool Foobar;
        }
    }
}

Thanks for the detailed write up. I wonder if we should just omit properties. It would be a breaking change, so bump the major. But I think it would be a sensible change

Thanks for the detailed write up. I wonder if we should just omit properties. It would be a breaking change, so bump the major. But I think it would be a sensible change

For me that would be perfectly fine, but OTOH maybe people use this feature in the wild. I think the best-case scenario (but also the one with the most effort) would be:

  • Warn or throw an error during compilation if an expression-bodied member is used until the issue is fixed (would be perfectly fine for me if any of the items below is implemented)
  • I agree that by default properties should be excluded, but it would probably also be wise to make this configurable somehow for AttributeTargets.Assembly, AttributeTargets.Module and AttributeTargets.Class. Starting with a new major release I agree that properties should be excluded by default.

I think a good first-step for the current minor releases would be to simply warn during compilation if an expression-bodied member is used and omit the IL, although I'm not sure if System.InvalidProgramException occurs only in some cases when using expression-bodied member. If so, maybe a flag for the <MethodTimer/> weaver in FodyWeavers.xml like ApplyToPropertyMethods with default to true for maximum compatibility.

can u try 2.3.3 and see if it fixes the InvalidProgramException

BTW to be raising issues you should be a patron of Fody.