runtime: aspnetcore tests having Dynamic.Proxy fails on ppc64le architecture
Description
Around 6000+ aspnetcore tests which are using Dynamic.Proxy are failing on ppc64le with mono complier.
Reproduction Steps
build aspnetcore on ppc64le using cross built net8 rc2 and run tests.
Expected behavior
All tests should pass
Actual behavior
We get below error for 6000+ tests
Microsoft.AspNetCore.Server.Kestrel.Core.Tests.ConnectionContextTests.ParameterlessAbortCreateConnectionAbortedException
System.InvalidCastException : Specified cast is not valid.
at Castle.DynamicProxy.Internal.AttributeUtil.ReadAttributeValue(CustomAttributeTypedArgument argument)
at Castle.DynamicProxy.Internal.AttributeUtil.GetArguments(IList`1 constructorArguments, Type[]& constructorArgTypes, Object[]& constructorArgs)
at Castle.DynamicProxy.Internal.AttributeUtil.CreateInfo(CustomAttributeData attribute)
at Castle.DynamicProxy.Internal.AttributeUtil.GetNonInheritableAttributes(MemberInfo member)+MoveNext()
at System.Linq.Enumerable.SelectEnumerableIterator`2[[Castle.DynamicProxy.CustomAttributeInfo, Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc],[System.Reflection.Emit.CustomAttributeBuilder, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at Castle.DynamicProxy.Generators.MetaProperty.BuildPropertyEmitter(ClassEmitter classEmitter)
at Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementProperty(ClassEmitter emitter, MetaProperty property, ProxyGenerationOptions options)
at Castle.DynamicProxy.Contributors.CompositeTypeContributor.Generate(ClassEmitter class, ProxyGenerationOptions options)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.<>c__DisplayClass1_0.<GenerateCode>b__0(String n, INamingScope s)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstancePexProtected()
at Moq.PexProtector.Invoke(Action action)
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstance()
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].OnGetObject()
at Moq.Mock.get_Object()
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Object()
at Microsoft.AspNetCore.Server.Kestrel.Core.Tests.ConnectionContextTests.ParameterlessAbortCreateConnectionAbortedException() in /_/src/Servers/Kestrel/Core/test/ConnectionContextTests.cs:line 21
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
0.0321365s✘ Microsoft.AspNetCore.Server.Kestrel.Core.Tests.ConnectionDispatcherTests.OnConnectionCreatesLogScopeWithConnectionId
System.InvalidCastException : Specified cast is not valid.
at Castle.DynamicProxy.Internal.AttributeUtil.ReadAttributeValue(CustomAttributeTypedArgument argument)
at Castle.DynamicProxy.Internal.AttributeUtil.GetArguments(IList`1 constructorArguments, Type[]& constructorArgTypes, Object[]& constructorArgs)
at Castle.DynamicProxy.Internal.AttributeUtil.CreateInfo(CustomAttributeData attribute)
at Castle.DynamicProxy.Internal.AttributeUtil.GetNonInheritableAttributes(MemberInfo member)+MoveNext()
at System.Linq.Enumerable.SelectEnumerableIterator`2[[Castle.DynamicProxy.CustomAttributeInfo, Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc],[System.Reflection.Emit.CustomAttributeBuilder, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at Castle.DynamicProxy.Generators.MetaProperty.BuildPropertyEmitter(ClassEmitter classEmitter)
at Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementProperty(ClassEmitter emitter, MetaProperty property, ProxyGenerationOptions options)
at Castle.DynamicProxy.Contributors.CompositeTypeContributor.Generate(ClassEmitter class, ProxyGenerationOptions options)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.<>c__DisplayClass1_0.<GenerateCode>b__0(String n, INamingScope s)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstancePexProtected()
at Moq.PexProtector.Invoke(Action action)
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstance()
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].OnGetObject()
at Moq.Mock.get_Object()
at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Object()
at Microsoft.AspNetCore.Server.Kestrel.Core.Tests.ConnectionDispatcherTests.OnConnectionCreatesLogScopeWithConnectionId() in /_/src/Servers/Kestrel/Core/test/ConnectionDispatcherTests.cs:line 33
--- End of stack trace from previous location ---
Output:
| [0.007s] TestLifetime Information: Starting test OnConnectionCreatesLogScopeWithConnectionId at 2023-10-17T17:03:42
| [0.039s] Microsoft.AspNetCore.Server.Kestrel.Core.Tests.ConnectionDispatcherTests Error: Test threw an exception.
| System.InvalidCastException: Specified cast is not valid.
| at Castle.DynamicProxy.Internal.AttributeUtil.ReadAttributeValue(CustomAttributeTypedArgument argument)
| at Castle.DynamicProxy.Internal.AttributeUtil.GetArguments(IList`1 constructorArguments, Type[]& constructorArgTypes, Object[]& constructorArgs)
| at Castle.DynamicProxy.Internal.AttributeUtil.CreateInfo(CustomAttributeData attribute)
| at Castle.DynamicProxy.Internal.AttributeUtil.GetNonInheritableAttributes(MemberInfo member)+MoveNext()
| at System.Linq.Enumerable.SelectEnumerableIterator`2[[Castle.DynamicProxy.CustomAttributeInfo, Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc],[System.Reflection.Emit.CustomAttributeBuilder, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
| at Castle.DynamicProxy.Generators.MetaProperty.BuildPropertyEmitter(ClassEmitter classEmitter)
| at Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementProperty(ClassEmitter emitter, MetaProperty property, ProxyGenerationOptions options)
| at Castle.DynamicProxy.Contributors.CompositeTypeContributor.Generate(ClassEmitter class, ProxyGenerationOptions options)
| at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
| at Castle.DynamicProxy.Generators.ClassProxyGenerator.<>c__DisplayClass1_0.<GenerateCode>b__0(String n, INamingScope s)
| at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
| at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
| at Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
| at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
| at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
| at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
| at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstancePexProtected()
| at Moq.PexProtector.Invoke(Action action)
| at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstance()
| at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].OnGetObject()
| at Moq.Mock.get_Object()
| at Moq.Mock`1[[Microsoft.AspNetCore.Connections.DefaultConnectionContext, Microsoft.AspNetCore.Connections.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Object()
| at Microsoft.AspNetCore.Server.Kestrel.Core.Tests.ConnectionDispatcherTests.OnConnectionCreatesLogScopeWithConnectionId() in /_/src/Servers/Kestrel/Core/test/ConnectionDispatcherTests.cs:line 33
| at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_0.<<InvokeTestMethodAsync>b__1>d[[Xunit.Sdk.IXunitTestCase, xunit.core, Version=2.4.2.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c]].MoveNext() in /_/src/xunit.execution/Sdk/Frameworks/Runners/TestInvoker.cs:line 264
| --- End of stack trace from previous location ---
| at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in /_/src/xunit.execution/Sdk/Frameworks/ExecutionTimer.cs:line 48
| at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in /_/src/xunit.core/Sdk/ExceptionAggregator.cs:line 90
| [0.055s] TestLifetime Information: Finished test OnConnectionCreatesLogScopeWithConnectionId in 0.0478395s
Regression?
No response
Known Workarounds
No response
Configuration
.NET 8 RC1 cross built for the linux-ppc64 target (using the Mono runtime by default).
dotnet --info
.NET SDK:
Version: 8.0.100-rc.2.23502.2
Commit: 0abacfc2b6
Runtime Environment:
OS Name: rhel
OS Version: 8
OS Platform: Linux
RID: linux-ppc64le
Base Path: /root/ashutosh/aspnetcore-crossbuild/aspnetcore/.dotnet/sdk/8.0.100-rc.2.23502.2/
.NET workloads installed:
There are no installed workloads to display.
Host:
Version: 8.0.0-rc.2.23479.6
Architecture: ppc64le
Commit: 0b25e38ad3
.NET SDKs installed:
8.0.100-rc.2.23502.2 [/root/ashutosh/aspnetcore-crossbuild/aspnetcore/.dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.0-ci [/root/ashutosh/aspnetcore-crossbuild/aspnetcore/.dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0-rc.2.23480.2 [/root/ashutosh/aspnetcore-crossbuild/aspnetcore/.dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 8.0.0-rc.2.23479.6 [/root/ashutosh/aspnetcore-crossbuild/aspnetcore/.dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
Other information
No response
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Comments: 26 (26 by maintainers)
Commits related to this issue
- [mono] [imt] Don't increment vt_slot for non-virtual generic methods (#94437) * [mono] [imt] Don't increment vt_slot for non-virtual generic methods Interfaces can have static generic methods, fo... — committed to dotnet/runtime by lambdageek 8 months ago
- [release/8.0-staging] [mono] [imt] Don't increment vt_slot for non-virtual generic methods (#94469) * [mono] [imt] Don't increment vt_slot for non-virtual generic methods Interfaces can have stat... — committed to dotnet/runtime by github-actions[bot] 8 months ago
- [release/6.0-staging] [mono] [imt] Don't increment vt_slot for non-virtual generic methods (#94478) Backport of #94437 to release/6.0-staging Fixes #93770 * [mono] [imt] Don't increment vt_slot f... — committed to dotnet/runtime by lambdageek 8 months ago
- [release/7.0-staging] [mono] [imt] Don't increment vt_slot for non-virtual generic methods (#94468) Backport of #94437 to release/7.0-staging Fixes #93770 * [mono] [imt] Don't increment vt_slo... — committed to dotnet/runtime by github-actions[bot] 8 months ago
It’s a problem in the IMT builder. When
build_imt_slots
iterates over all the methods of a particular interface, it manually keeps track of the currentvt_slot
for the methods of that interface starting frominterface_offset
. The logic for incrementingvt_slot
was incorrect: if there is a generic non-virtual method in the interface, the vt_slot was incremented when it should not have been. As a result the IMT builder added an incorrect implementing method for the IMT slot.https://github.com/dotnet/runtime/blob/69702c372a051580f76defc7ba899dde8fcd2723/src/mono/mono/metadata/object.c#L1599-L1600
these two lines need to be under an
if (m_method_is_virtual (method))
PR shortly.
I want to think a little bit harder whether we can make a test case - I’m not sure if we really depend on an IMT slot collision to exhibit the problem or if it will show up if I can make it show up even with a single method per IMT slot
This is indeed the change that introduces the regression:
The backports for .NET 6, 7, 8 have been merged.
Many of the test failures look like:
The IEnumerable that is
null
here is the one used at line 193:It should never be
null
since the method is implemented as:So, what method is getting called here … 🤔
To call the method, there is some casting from one interface to another (as can be seen in the stacktrace above).
Yea, rc2 mono with preview6 efcore - works. rc2 mono with preview7 efcore - exception.
I’m not sure precisely what changed over there, but there were some interesting changes between previews 6 and 7, like https://github.com/dotnet/efcore/pull/31003 for example.
So this is some behavior difference between Mono and CoreCLR that efcore stubmled on. Unfortunately debugging isn’t super helpful yet.
We have built aspnetcore rc2 tag code using .NET8 rc2 SDK with mono and ran aspnetcore tests then observed these failures. To run single aspnetcore test which fails you can use below command
@tmds Maybe https://github.com/dotnet/runtime/pull/87406 /cc @ivanpovazan
(I’m looking through https://github.com/dotnet/runtime/compare/v8.0.0-preview.6.23329.7...v8.0.0-preview.7.23375.6 )
@tmds you said you can repro the failure on x64? Could you share the repro steps