-
Notifications
You must be signed in to change notification settings - Fork 79
AllowChangingInputArguments System.InvalidProgramException #127
Copy link
Copy link
Open
Description
The Following code gives the following runtime error:
System.InvalidProgramException Common Language Runtime detected an invalid program.
Minimalistic Setup:
using MethodBoundaryAspect.Fody.Attributes;
using System.Reflection;
internal class Program
{
[AllowChangingInputArguments]
public class AsyncWrapperAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("testing");
}
}
class FodyTestClass
{
[AsyncWrapper]
public bool FillGuids(out Guid guid1, out Guid guid2)
{
guid1 = Guid.NewGuid();
guid2 = Guid.NewGuid();
return true;
}
}
private static void Main(string[] args)
{
FodyTestClass fodyTestClass = new FodyTestClass();
fodyTestClass.FillGuids(out Guid guid1, out Guid guid2);
Console.WriteLine("Hello, World!");
}
}
Full Code: Method wrapper for WPF running functions without SynchronizationContext
Goal: Being able to set out params
using MethodBoundaryAspect.Fody.Attributes;
using System.Reflection;
internal class Program
{
[AllowChangingInputArguments]
public class AsyncWrapperAttribute : OnMethodBoundaryAspect
{
private static AsyncLocal<bool> isExecuting = new AsyncLocal<bool>();
public override void OnEntry(MethodExecutionArgs args)
{
if (isExecuting.Value)
return;
var method = args.Method as MethodInfo;
if (method == null)
throw new InvalidOperationException("Method is not a valid MethodInfo.");
var parameters = method.GetParameters();
object[] arguments = new object[args.Arguments.Length];
Array.Copy(args.Arguments, arguments, args.Arguments.Length);
isExecuting.Value = true;
try
{
object result = null;
ExecuteWithoutSynchronizationContext(() =>
{
object[] tempArguments = new object[arguments.Length];
Array.Copy(arguments, tempArguments, arguments.Length);
result = method.Invoke(args.Instance, tempArguments);
for (int i = 0; i < parameters.Length; i++)
if (parameters[i].IsOut || parameters[i].ParameterType.IsByRef)
args.Arguments[i] = tempArguments[i];
});
args.ReturnValue = result;
args.FlowBehavior = FlowBehavior.Return;
}
finally
{
isExecuting.Value = false;
}
}
private void ExecuteWithoutSynchronizationContext(Action action)
{
var currentContext = SynchronizationContext.Current;
try
{
SynchronizationContext.SetSynchronizationContext(null);
action();
}
finally
{
SynchronizationContext.SetSynchronizationContext(currentContext);
}
}
}
class FodyTestClass
{
[AsyncWrapper]
public bool FillGuids(out Guid guid1, out Guid guid2)
{
guid1 = Guid.NewGuid();
guid2 = Guid.NewGuid();
return true;
}
}
private static void Main(string[] args)
{
FodyTestClass fodyTestClass = new FodyTestClass();
fodyTestClass.FillGuids(out Guid guid1, out Guid guid2);
Console.WriteLine("Hello, World!");
}
}
Minimal Repro
Running Minimalistic Setup will give the Exception on the following line:
fodyTestClass.FillGuids(out Guid guid1, out Guid guid2);
Running the Full code without the AllowChangingInputArguments attribute results in:
not set parameters (guid1 & guid2 both are Guid.Empty) in the Main function after line
fodyTestClass.FillGuids(out Guid guid1, out Guid guid2);
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels