runtime icon indicating copy to clipboard operation
runtime copied to clipboard

Do not check object references for equality after hot reload

Open buyaa-n opened this issue 3 years ago • 9 comments
trafficstars

RuntimeType member's cache is purged after hot reload, therefore same member references are not equal after hotreload which causing issue like mentioned in Hot Reload breaks MethodInfo equality

Updated/added Object.Equals overloads to compare metadata token and module in case hot reload taken place instead of comparing object references.

Fixes https://github.com/dotnet/runtime/issues/69427

buyaa-n avatar Jul 28 '22 16:07 buyaa-n

Tagging subscribers to this area: @dotnet/area-system-reflection See info in area-owners.md if you want to be subscribed.

Issue Details

RuntimeType member's cache is purged after hot reload, therefore same member references are not equal after hotreload which causing issue like mentioned in Hot Reload breaks MethodInfo equality

Updated/added Object.Equals overloads to compare metadata token and module in case hot reload taken place instead of comparing object references.

Fixes https://github.com/dotnet/runtime/issues/69427

Author: buyaa-n
Assignees: -
Labels:

area-System.Reflection

Milestone: -

msftbot[bot] avatar Jul 28 '22 16:07 msftbot[bot]

CI test failures on Microsoft.CSharp.RuntimeBinder.Tests, System.Dynamic.Runtime.Tests, System.Composition.Convention.Tests etc could be related, I can repro locally and seems not reproduceable in other branch, looking

buyaa-n avatar Aug 03 '22 18:08 buyaa-n

Comparing RuntimeMethodInfo handles for equality causing the CI test failures in above projects, reverted that

buyaa-n avatar Aug 03 '22 23:08 buyaa-n

Do you understand why? Have you been able to create a small standalone repro using just the reflection APIs?

No, I could not understood why, a typical failure log looks like this:

Dynamic.Operator.Tests.PlusEqualTypeTests.Byte [FAIL]
System.ArgumentException : ParameterExpression of type 'System.String' cannot be used for delegate parameter of type 'System.Object'
        Stack Trace:
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(954,0): at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expres
  sion& body, ReadOnlyCollection`1 parameters, String paramName)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(717,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String na
  me, Boolean tailCall, IEnumerable`1 parameters)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Runtime\CompilerServices\CallSiteBinder.cs(192,0): at System.Runtime.CompilerServices.CallSiteBinder.Stitch[T](Expression bindi
  ng, LambdaSignature`1 signature)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Runtime\CompilerServices\CallSiteBinder.cs(132,0): at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 sit
  e, Object[] args)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Dynamic\UpdateDelegates.Generated.cs(157,0): at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0
  arg0, T1 arg1)
          D:\dotnet\pr2\src\libraries\System.Dynamic.Runtime\tests\Dynamic.Context\Conformance.dynamic.context.operator.compound.type.PlusEqual.cs(76,0): at Dynamic.Operator.Tests.PlusEqualTypeTests.B
  yte()
             at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
          D:\dotnet\pr2\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(69,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

just know reverting back the Equals logic fixes those failures, will dig more

buyaa-n avatar Aug 04 '22 00:08 buyaa-n

Another log

System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByCodePage_WithDisallowedEncoding_Throws(encodingName: "utf-7", codePage: 65000) [FAIL]
        System.ArgumentException : ParameterExpression of type 'System.Text.EncodingProvider' cannot be used for delegate parameter of type 'System.Reflection.Binder'
        Stack Trace:
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(954,0): at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expres
  sion& body, ReadOnlyCollection`1 parameters, String paramName)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(717,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String na
  me, Boolean tailCall, IEnumerable`1 parameters)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(689,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean t
  ailCall, IEnumerable`1 parameters)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(651,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Parameter
  Expression[] parameters)
          D:\dotnet\pr2\src\libraries\System.Runtime\tests\System\Text\EncodingTests.cs(43,0): at System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByCodePage_WithDisallowedEncoding_Throws(Stri
  ng encodingName, Int32 codePage)
             at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
          D:\dotnet\pr2\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(64,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
        System.ArgumentException : ParameterExpression of type 'System.Text.EncodingProvider' cannot be used for delegate parameter of type 'System.Reflection.Binder'
        Stack Trace:
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(954,0): at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expres
  sion& body, ReadOnlyCollection`1 parameters, String paramName)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(717,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String na
  me, Boolean tailCall, IEnumerable`1 parameters)
      System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByEncodingName_WithDisallowedEncoding_Throws(encodingName: "utf-7", codePage: 65000) [FAIL]
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(689,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean t
  ailCall, IEnumerable`1 parameters)
          D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(651,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Parameter
  Expression[] parameters)
          D:\dotnet\pr2\src\libraries\System.Runtime\tests\System\Text\EncodingTests.cs(71,0): at System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByEncodingName_WithDisallowedEncoding_Throws(
  String encodingName, Int32 codePage)
             at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
          D:\dotnet\pr2\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(64,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

buyaa-n avatar Aug 04 '22 00:08 buyaa-n

Looking at the test failures - the reflected type needs to be also included in Equals method.

jkotas avatar Aug 05 '22 00:08 jkotas

@buyaa-n I have pushed a commit with a bunch of perf tweaks and simplifications. The commit description has the details. Let me know if it looks good to you or if you have any questions.

jkotas avatar Aug 06 '22 13:08 jkotas

@buyaa-n I have pushed a commit with a bunch of perf tweaks and simplifications. The commit description has the details. Let me know if it looks good to you or if you have any questions.

Thanks for the description, makes sense to me

buyaa-n avatar Aug 06 '22 17:08 buyaa-n

Looks good to me, modulo the last two comments

jkotas avatar Aug 08 '22 00:08 jkotas

Failures unrelated and known issue, merging

buyaa-n avatar Aug 08 '22 17:08 buyaa-n