-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EnC: Mono throws when member accessibility is changed #108097
Comments
@lambdageek ptal. Would be nice to get fixed for .NET 9, if not too difficult. |
@tmat what's allowed? changing toward more visibility? or is runtime/src/mono/mono/component/hot_reload.c Lines 2235 to 2237 in b5f5349
|
I can't really tell without trying it, but this seems fairly straightforward (although I can't tell how risky it might be for .NET 9): @tmat what happens if an SRE method was JITed with a |
attn @tommcdon |
Any visibility changes would be allowed. |
Not sure I understand the scenario. What does SRE mean? System.Reflection.Emit? |
I'm thinking of a scenario like this: using System.Reflection;
using System.Reflection.Emit;
public class C {
/*private*/ public int X; /// EnC: change this
public void Increment()
{
X++;
}
}
public class Program
{
public static void Main()
{
var c = new C();
var f1 = GenerateGetter();
while (true)
{
c.Increment();
Foo(f1, c); // Q: this should always succeed?
var f2 = GenerateGetter();
Foo(f2, c); // Q: after edit, this should throw FieldAccessException?
System.Threading.Thread.Sleep(1000);
}
}
public static void Foo(Func<C,int> func, C c)
{
int i = func(c);
Console.WriteLine ($"i = {i}");
}
public static Func<C,int> GenerateGetter()
{
var fi = typeof(C).GetField("X", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var an = new AssemblyName("x1");
var ab = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndCollect);
var modb = ab.DefineDynamicModule(an.FullName);
var tb = modb.DefineType("GetterHolder", TypeAttributes.Public);
var methodName = "GetX";
var mb = tb.DefineMethod(methodName, MethodAttributes.Public | MethodAttributes.Static, typeof(int), [ typeof(C) ]);
var ilg = mb.GetILGenerator();
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldfld, fi);
ilg.Emit(OpCodes.Ret);
var ti = tb.CreateType();
var mi = ti.GetMethod (methodName, BindingFlags.Public | BindingFlags.Static);
return (Func<C,int>)Delegate.CreateDelegate(typeof(Func<C,int>), mi);
}
} Suppose you run this app and then change |
I think so, as long as |
Thanks. In that case, I think the change I summarized in #108097 (comment) should be sufficient |
Just so I'm clear, are any of the 3 things that might happen what is supposed to happen when EnC can't continue? |
If Roslyn sends invalid update to the runtime the behavior is undefined. It's Roslyn's responsibility to block rude edits. That said, as much as possible a better failure than crashing VS or debugger would be certainly desirable. Ideally, the runtime would send message to the debugger that EnC/Hot Reload failed and an error code. |
However, I can see that it might be hard to do so if an issue is found in the middle of updating various data structures (i.e. rolling back partial updates). |
@tmat Do we also need to support changing method/property/event/nested class accessibility? or is this just about fields? |
@lambdageek All members and types. |
Description
Mono throws when member accessibility is changed during debugging
Reproduction Steps
Use Roslyn build from PR: dotnet/roslyn#75191 for repro.
@code
block inCounter.razor
with:IncrementCount
and F5.Expected behavior
Assignment to
x
is successfully executed.Actual behavior
One of the following:
1)
The Blazor app crashes and disconnects:
Regression?
No
Known Workarounds
No response
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: