-
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
Avoiding discarding exception details of MissingMethodException
in RuntimeType.CreateInstanceImpl
#108876
base: main
Are you sure you want to change the base?
Avoiding discarding exception details of MissingMethodException
in RuntimeType.CreateInstanceImpl
#108876
Conversation
…issingMethodException`)
…ingMethodException`)
} | ||
catch (MissingMethodException) { invokeMethod = null; } | ||
|
||
MethodBase? invokeMethod = binder.BindToMethod(bindingAttr, cons, ref args, null, culture, null, out object? state); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there any tests that highlight the differences between the main branch and the pull request?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tested by below steps:
- Build .NET Runtime
- Clone with the following command:
git clone https://github.com/Takym/runtime.git -b AvoidingDiscardingExceptionDetails/2024_10
- Enter to the repository:
cd runtime
- Run the build command:
build
- Clone with the following command:
- Install .NET Runtime
- Open the installer directory:
explorer .\artifacts\packages\Debug\Shipping
- Execute following installers:
dotnet-runtime-10.0.0-dev-win-x64.exe
dotnet-apphost-pack-10.0.0-dev-win-x64.msi
dotnet-targeting-pack-10.0.0-dev-win-x64.msi
- Open the installer directory:
- Create a new project with
dotnet new console
in a new empty directory. - Rewrite
Program.cs
:using System.Globalization; using System.Reflection; try { Activator.CreateInstance(typeof(object), BindingFlags.CreateInstance, new MyBinder(), null, null, null); } catch (Exception e) { Console.WriteLine(e.ToString()); } class MyBinder : Binder { public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object?[] args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? names, out object? state) => throw new MissingMethodException("Hello, World!!"); public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo? culture) => throw new NotImplementedException(); public override object ChangeType(object value, Type type, CultureInfo? culture) => throw new NotImplementedException(); public override void ReorderArgumentArray(ref object?[] args, object state) => throw new NotImplementedException(); public override MethodBase? SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[]? modifiers) => throw new NotImplementedException(); public override PropertyInfo? SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type? returnType, Type[]? indexes, ParameterModifier[]? modifiers) => throw new NotImplementedException(); }
- Running on .NET 9.0 or .NET 8.0:
dotnet run
System.MissingMethodException: Constructor on type 'System.Object' not found. at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) at Program.<Main>$(String[] args)
- Running on .NET 10.0-dev:
dotnet run --roll-forward LatestMajor
System.MissingMethodException: Constructor on type 'System.Object' not found. ---> System.MissingMethodException: Hello, World!! at MyBinder.BindToMethod(BindingFlags bindingAttr, MethodBase[] match, Object[]& args, ParameterModifier[] modifiers, CultureInfo culture, String[] names, Object& state) at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) --- End of inner exception stack trace --- at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) at Program.<Main>$(String[] args)
Key Differences
- My PR one contains all stack traces. So, it helps to analyze the error.
- Also, you can check the inner exception message. This means you can know the root cause of the error.
- I fixed this PR from no catching to rethrow for rewriting a message with the type's full name.
- Initially, I removed the try-catch block to preserve the whole stack traces.
- I got pointed out to include the original exception as an inner exception into a new exception to include the type full name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should uninstall .NET 10.0-dev after behavior testing for your computer safety.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tested by below steps:
That looks great, thank you. Also adding a unit test would be great, you can add the test in https://github.com/dotnet/runtime/blob/main/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also adding a unit test would be great
yeah, that's exactly what i was getting at, so we can prevent this behavior from popping up again in the future. adding a unit test would be great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a unit test in the commit e4a8824. I have pushed the commit to test it online with CI. Testing offline (local PC) is not finished yet. I will be trying to run it later.
src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
Outdated
Show resolved
Hide resolved
…github.com/Takym/runtime into AvoidingDiscardingExceptionDetails/2024_10
…hodException properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good; thanks!
src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs
Show resolved
Hide resolved
…/ActivatorTests.cs Co-authored-by: Steve Harter <steveharter@users.noreply.github.com>
…/ActivatorTests.cs Co-authored-by: Steve Harter <steveharter@users.noreply.github.com>
src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs
Outdated
Show resolved
Hide resolved
…/ActivatorTests.cs Co-authored-by: kasperk81 <83082615+kasperk81@users.noreply.github.com>
I found the code that
try { ... } catch (MissingMethodException) { invokeMethod = null; }
and immediately later, re-throwingMissingMethodException
ifinvokeMethod
was null. This code removes stack trace information. So, I think debugging or analyzing gets difficult. I kept the code throwingMissingMethodException
becausebinder.BindToMethod
may return null.