Skip to content
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

`Cannot box IsByRefLike type 'System.ReadOnlySpan'1'` in Forms designer tests with 6.0 #14809

Closed
directhex opened this issue Jun 5, 2019 · 10 comments · Fixed by #14863
Assignees

Comments

@directhex
Copy link
Contributor

@directhex directhex commented Jun 5, 2019

https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=2734169

29 individual instances of:

error : Xamarin.Designer.Forms.Tests.Loader.XamarinFormsLoaderTests.ProxyTypeBaseTypeHasProtectedInternalConstructor [/Users/vsts/agent/2.150.3/work/1/s/Xamarin.Designer.Forms/Designer.proj]
  System.BadImageFormatException : Cannot box IsByRefLike type 'System.ReadOnlySpan`1'
  
  
  Server stack trace: 
    at (wrapper managed-to-native) System.Runtime.Remoting.Proxies.RealProxy.InternalGetTransparentProxy(System.Runtime.Remoting.Proxies.RealProxy,string)
    at System.Runtime.Remoting.Proxies.RealProxy.GetTransparentProxy () [0x0004d] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Remoting.RemotingServices.GetOrCreateClientIdentity (System.Runtime.Remoting.ObjRef objRef, System.Type proxyType, System.Object& clientProxy) [0x000ce] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Remoting.RemotingServices.GetRemoteObject (System.Runtime.Remoting.ObjRef objRef, System.Type proxyType) [0x00000] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Remoting.RemotingServices.GetProxyForRemoteObject (System.Runtime.Remoting.ObjRef objref, System.Type classToProxy) [0x0001b] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Remoting.RemotingServices.Unmarshal (System.Runtime.Remoting.ObjRef objectRef, System.Boolean fRefine) [0x0007a] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Remoting.RemotingServices.Unmarshal (System.Runtime.Remoting.ObjRef objectRef) [0x00000] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Remoting.ObjRef.GetRealObject (System.Runtime.Serialization.StreamingContext context) [0x0000f] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.ObjectManager.ResolveObjectReference (System.Runtime.Serialization.ObjectHolder holder) [0x00010] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.ObjectManager.DoFixups () [0x0007f] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize (System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Runtime.Serialization.Formatters.Binary.__BinaryParser serParser, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) [0x00077] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) [0x000a2] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) [0x00000] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck) [0x00000] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) [0x00000] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) [0x00000] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at System.Runtime.Remoting.RemotingServices.DeserializeCallData (System.Byte[] array) [0x0001c] in <a0ec3ed589fe45b38ea1940a8867d892>:0 
    at (wrapper xdomain-invoke) NUnit.ApplicationDomain.TestMethodInformation.get_OutputStream()
    at (wrapper remoting-invoke-with-check) NUnit.ApplicationDomain.TestMethodInformation.get_OutputStream()
    at NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute (NUnit.ApplicationDomain.TestMethodInformation testMethodInfo) [0x0000d] in <fda6d6a43f354b4ea28adffc55ccbb31>:0 
    at (wrapper remoting-invoke-with-check) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(NUnit.ApplicationDomain.TestMethodInformation)
    at (wrapper xdomain-dispatch) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(object,byte[]&,byte[]&)
  
  Exception rethrown at [0]: 
    at (wrapper xdomain-invoke) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(NUnit.ApplicationDomain.TestMethodInformation)
    at (wrapper remoting-invoke-with-check) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(NUnit.ApplicationDomain.TestMethodInformation)
    at NUnit.ApplicationDomain.Internal.ParentAppDomainRunner.Run (NUnit.Framework.Interfaces.ITest test, System.Type appDomainFactoryType) [0x000e0] in <fda6d6a43f354b4ea28adffc55ccbb31>:0 
    at NUnit.Framework.RunInApplicationDomainAttribute.RunInApplicationDomain (NUnit.Framework.Interfaces.ITest testDetails) [0x00008] in <fda6d6a43f354b4ea28adffc55ccbb31>:0 
    at NUnit.Framework.RunInApplicationDomainAttribute.BeforeTest (NUnit.Framework.Interfaces.ITest testDetails) [0x0001b] in <fda6d6a43f354b4ea28adffc55ccbb31>:0 
    at NUnit.Framework.Internal.Commands.TestActionCommand+<>c__DisplayClass0_0.<.ctor>b__0 (NUnit.Framework.Internal.TestExecutionContext context) [0x00011] in <5d5da92be75c4740b706725e01231009>:0 
    at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand+<>c__DisplayClass1_0.<Execute>b__0 () [0x00000] in <5d5da92be75c4740b706725e01231009>:0 
    at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone (NUnit.Framework.Internal.TestExecutionContext context, System.Action action) [0x00000] in <5d5da92be75c4740b706725e01231009>:0 

@lambdageek

@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Jun 5, 2019

Standalone reproduction, Mono JIT compiler version 6.0.0.281 (2019-02/a90018bed80 Wed Jun 5 11:09:43 EDT 2019)

Extract attached Repro14809.zip
and then

msbuild /t:Restore
msbuild /t:Build
mono bin/Debug/nunit3-console.exe bin/Debug/net47/Repro14809.dll

Expected output: 1 test failure.

Actual output:

NUnit Console Runner 3.9.0
Copyright (c) 2018 Charlie Poole, Rob Prouse

Runtime Environment
OS Version: MacOSX 18.6.0.0
CLR Version: 4.0.30319.42000

Test Files
bin/Debug/net47/Repro14809.dll

Errors, Failures and Warnings

  1. Error : nunitthingie.Test.TestCase
    System.BadImageFormatException : Cannot box IsByRefLike type 'System.ReadOnlySpan`1'

Server stack trace:
at (wrapper managed-to-native) System.Runtime.Remoting.Proxies.RealProxy.InternalGetTransparentProxy(System.Runtime.Remoting.Proxies.RealProxy,string)
at System.Runtime.Remoting.Proxies.RealProxy.GetTransparentProxy () [0x0004d] in :0
at System.Runtime.Remoting.RemotingServices.GetOrCreateClientIdentity (System.Runtime.Remoting.ObjRef objRef, System.Type proxyType, System.Object& clientProxy) [0x000ce] in :0
at System.Runtime.Remoting.RemotingServices.GetRemoteObject (System.Runtime.Remoting.ObjRef objRef, System.Type proxyType) [0x00000] in :0
at System.Runtime.Remoting.RemotingServices.GetProxyForRemoteObject (System.Runtime.Remoting.ObjRef objref, System.Type classToProxy) [0x0001b] in :0
at System.Runtime.Remoting.RemotingServices.Unmarshal (System.Runtime.Remoting.ObjRef objectRef, System.Boolean fRefine) [0x0007a] in :0
at System.Runtime.Remoting.RemotingServices.Unmarshal (System.Runtime.Remoting.ObjRef objectRef) [0x00000] in :0
at System.Runtime.Remoting.ObjRef.GetRealObject (System.Runtime.Serialization.StreamingContext context) [0x0000f] in :0
at System.Runtime.Serialization.ObjectManager.ResolveObjectReference (System.Runtime.Serialization.ObjectHolder holder) [0x00010] in :0
at System.Runtime.Serialization.ObjectManager.DoFixups () [0x0007f] in :0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize (System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Runtime.Serialization.Formatters.Binary.__BinaryParser serParser, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) [0x00077] in :0
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) [0x000a2] in :0
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) [0x00000] in :0
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck) [0x00000] in :0
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) [0x00000] in :0
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) [0x00000] in :0
at System.Runtime.Remoting.RemotingServices.DeserializeCallData (System.Byte[] array) [0x0001c] in :0
at (wrapper xdomain-invoke) NUnit.ApplicationDomain.TestMethodInformation.get_OutputStream()
at (wrapper remoting-invoke-with-check) NUnit.ApplicationDomain.TestMethodInformation.get_OutputStream()
at NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute (NUnit.ApplicationDomain.TestMethodInformation testMethodInfo) [0x0000b] in <87cd1201576d4c378bf53a06e866eaaa>:0
at (wrapper remoting-invoke-with-check) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(NUnit.ApplicationDomain.TestMethodInformation)
at (wrapper xdomain-dispatch) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(object,byte[]&,byte[]&)

Exception rethrown at [0]:
at (wrapper xdomain-invoke) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(NUnit.ApplicationDomain.TestMethodInformation)
at (wrapper remoting-invoke-with-check) NUnit.ApplicationDomain.Internal.InDomainTestMethodRunner.Execute(NUnit.ApplicationDomain.TestMethodInformation)
at NUnit.ApplicationDomain.Internal.ParentAppDomainRunner.Run (NUnit.Framework.Interfaces.ITest test, System.Type appDomainFactoryType) [0x000bf] in <87cd1201576d4c378bf53a06e866eaaa>:0
at NUnit.Framework.RunInApplicationDomainAttribute.RunInApplicationDomain (NUnit.Framework.Interfaces.ITest testDetails) [0x00007] in <87cd1201576d4c378bf53a06e866eaaa>:0
at NUnit.Framework.RunInApplicationDomainAttribute.BeforeTest (NUnit.Framework.Interfaces.ITest testDetails) [0x00017] in <87cd1201576d4c378bf53a06e866eaaa>:0
at NUnit.Framework.Internal.Commands.TestActionCommand+<>c__DisplayClass0_0.<.ctor>b__0 (NUnit.Framework.Internal.TestExecutionContext context) [0x00011] in <5d5da92be75c4740b706725e01231009>:0
at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand+<>c__DisplayClass1_0.b__0 () [0x00000] in <5d5da92be75c4740b706725e01231009>:0
at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone (NUnit.Framework.Internal.TestExecutionContext context, System.Action action) [0x00000] in <5d5da92be75c4740b706725e01231009>:0

Run Settings
DisposeRunners: True
WorkDirectory: /Users/alklig/Projects/Repro14809/Repro14809
ImageRuntimeVersion: 4.0.30319
ImageTargetFrameworkName: .NETFramework,Version=v4.7
ImageRequiresX86: False
ImageRequiresDefaultAppDomainAssemblyResolver: False
NumberOfTestWorkers: 12

Test Run Summary
Overall result: Failed
Test Count: 1, Passed: 0, Failed: 1, Warnings: 0, Inconclusive: 0, Skipped: 0
Failed Tests - Failures: 0, Errors: 1, Invalid: 0
Start time: 2019-06-05 19:45:14Z
End time: 2019-06-05 19:45:15Z
Duration: 1.065 seconds

Results (nunit3) saved as TestResult.xml

@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Jun 5, 2019

Shorter repro, no nunit or msbuild. compile with csc Repro14809.cs, run with mono Repro14809.exe

using System;
using System.IO;

public class Repro14809 {
	public static void Main ()
	{
		var a = new A ();
		a.Test ();
	}

}

public class A {
	public A () {}

	public void Test ()
	{
		var ad = MakeAD();

		I i = (I)ad.CreateInstanceAndUnwrap (typeof (A).Assembly.FullName, nameof (T));

		var w = i.GetWriter ();

		w.WriteLine ("abcd");
	}

	public AppDomain MakeAD ()
	{
		return AppDomain.CreateDomain ("other domain");
	}

}

public interface I {
	TextWriter GetWriter ();

}

public class T : MarshalByRefObject, I {
	public T () {
		writer = TextWriter.Null; //Console.Out;
	}

	private TextWriter writer;

	public virtual TextWriter GetWriter ()
	{
		return writer;
	}
}
@directhex

This comment has been minimized.

Copy link
Contributor Author

@directhex directhex commented Jun 5, 2019

This definitely worked in old versions. Do you need a bisect?

@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Jun 5, 2019

@directhex yea, a bisect would be helpful. Although I have a sneaking suspicion the bisect will just point to #11111 which first implemented IsByRefLike in Mono.

(Updated the repro - TextWriter.Null instead of Console.Out also throws the exception. So it's probably something in the base TextWriter)

@directhex

This comment has been minimized.

Copy link
Contributor Author

@directhex directhex commented Jun 5, 2019

Interestingly, no, ab51a81 bisects good.

@lewing

This comment has been minimized.

Copy link
Member

@lewing lewing commented Jun 5, 2019

I think it is the new ReadOnlySpan overloads in TextWriter xunit/xunit#1791

@directhex

This comment has been minimized.

Copy link
Contributor Author

@directhex directhex commented Jun 5, 2019

I expect it'll be some kind of big-ass CoreFX-related import, but have started a full bisect now. Will report in in the morning.

@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Jun 5, 2019

@lewing Thanks! that's helpful. Looks like we can't make transparent proxies for any class that has a IsByRefLike argument. Trimmed down example coming soon.

I think probably method-to-ir is throwing too eagerly when it is making a box in handle_constrained_call - it should instead generate IR that throws when it is executed.

@mono mono deleted a comment from wahyu81 Jun 5, 2019
@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Jun 5, 2019

Even smaller standalone repro. The presence of O.M1 is enough to trigger the BadImageFormatException. I'm now thinking it's mono_marshal_get_remoting_invoke_for_target that needs to change.

using System;

public class Repro14809 {
	public static void Main ()
	{
		var ad = AppDomain.CreateDomain ("other domain");

		O o = (O)ad.CreateInstanceAndUnwrap (typeof (Repro14809).Assembly.FullName, nameof (Z));

		Console.WriteLine ("{0}", o != null);
	}
}

public ref struct MyByRefLikeStruct {}

public interface O {
	void M1 (MyByRefLikeStruct s);
}

public class Z : MarshalByRefObject, O {
	public Z () {}

	public void M1 (MyByRefLikeStruct s) {}
}
lambdageek added a commit to lambdageek/mono that referenced this issue Jun 6, 2019
…truct arguments

If we have a ref struct and a method that takes it as an argument:

```
[Serializable]
public ref struct R {
  public int i;
}

public interface I {
  public void M1 (R r, SomeClass o);
}

public class M : MarshalByRefObject, I {
  public void M1 (R r, SomeClass o) { ... }
}
```

If we create an instance of M in another domain and try to call it:
```
  I obj = (I)otherDomain.CreateInstanceAndUnwrap (typeof(M).Assembly.FullName,
  nameof(M));
  R r;
  r.i = 42;
  SomeClass o = ...;
  obj.M1 (r, o);
```

Mono will need to create a wrapper that can invoke M.M1 in the other domain.
The way the wrapper works in `mono_marshal_get_xappdomain_invoke` is by
creating an array of all the arguments that need to be serialized (see
`mono_get_xdomain_marshal_type`) and then serializing the whole array (by
calling out to `System.Runtime.Remoting.RemotingServices.SerializeCallData`).
In the example it would make a two element array and try to serialize `r` and
`o` into it. For valuetypes it normally does this by boxing the argument.
However since `R` is a ref-struct, boxing it is not allowed.

This works on .NET Framework.

However for Mono we would need to serilize `R` without boxing it, which seems
challenging with our current setup.

So for now we generate a wrapper that just throws a NotImplementedException if
it is ever called.

This fixes mono#14809 (in that marshalling a
TextWriter across domains works again) but in an unsatisfactory way (because
you can't call any of the ReadOnlySpan<char> overloads on the transparent proxy
object).
lambdageek added a commit to lambdageek/mono that referenced this issue Jun 6, 2019
monojenkins added a commit to monojenkins/mono that referenced this issue Jun 7, 2019
…truct arguments

If we have a ref struct and a method that takes it as an argument:

```
[Serializable]
public ref struct R {
  public int i;
}

public interface I {
  public void M1 (R r, SomeClass o);
}

public class M : MarshalByRefObject, I {
  public void M1 (R r, SomeClass o) { ... }
}
```

If we create an instance of M in another domain and try to call it:
```
  I obj = (I)otherDomain.CreateInstanceAndUnwrap (typeof(M).Assembly.FullName,
  nameof(M));
  R r;
  r.i = 42;
  SomeClass o = ...;
  obj.M1 (r, o);
```

Mono will need to create a wrapper that can invoke M.M1 in the other domain.
The way the wrapper works in `mono_marshal_get_xappdomain_invoke` is by
creating an array of all the arguments that need to be serialized (see
`mono_get_xdomain_marshal_type`) and then serializing the whole array (by
calling out to `System.Runtime.Remoting.RemotingServices.SerializeCallData`).
In the example it would make a two element array and try to serialize `r` and
`o` into it. For valuetypes it normally does this by boxing the argument.
However since `R` is a ref-struct, boxing it is not allowed.

This works on .NET Framework.

However for Mono we would need to serilize `R` without boxing it, which seems
challenging with our current setup.

So for now we generate a wrapper that just throws a NotImplementedException if
it is ever called.

This fixes mono#14809 (in that marshalling a
TextWriter across domains works again) but in an unsatisfactory way (because
you can't call any of the ReadOnlySpan<char> overloads on the transparent proxy
object).
monojenkins added a commit to monojenkins/mono that referenced this issue Jun 7, 2019
monojenkins added a commit to monojenkins/mono that referenced this issue Jun 7, 2019
…truct arguments

If we have a ref struct and a method that takes it as an argument:

```
[Serializable]
public ref struct R {
  public int i;
}

public interface I {
  public void M1 (R r, SomeClass o);
}

public class M : MarshalByRefObject, I {
  public void M1 (R r, SomeClass o) { ... }
}
```

If we create an instance of M in another domain and try to call it:
```
  I obj = (I)otherDomain.CreateInstanceAndUnwrap (typeof(M).Assembly.FullName,
  nameof(M));
  R r;
  r.i = 42;
  SomeClass o = ...;
  obj.M1 (r, o);
```

Mono will need to create a wrapper that can invoke M.M1 in the other domain.
The way the wrapper works in `mono_marshal_get_xappdomain_invoke` is by
creating an array of all the arguments that need to be serialized (see
`mono_get_xdomain_marshal_type`) and then serializing the whole array (by
calling out to `System.Runtime.Remoting.RemotingServices.SerializeCallData`).
In the example it would make a two element array and try to serialize `r` and
`o` into it. For valuetypes it normally does this by boxing the argument.
However since `R` is a ref-struct, boxing it is not allowed.

This works on .NET Framework.

However for Mono we would need to serilize `R` without boxing it, which seems
challenging with our current setup.

So for now we generate a wrapper that just throws a NotImplementedException if
it is ever called.

This fixes mono#14809 (in that marshalling a
TextWriter across domains works again) but in an unsatisfactory way (because
you can't call any of the ReadOnlySpan<char> overloads on the transparent proxy
object).
monojenkins added a commit to monojenkins/mono that referenced this issue Jun 7, 2019
marek-safar added a commit that referenced this issue Jun 7, 2019
…truct arguments

If we have a ref struct and a method that takes it as an argument:

```
[Serializable]
public ref struct R {
  public int i;
}

public interface I {
  public void M1 (R r, SomeClass o);
}

public class M : MarshalByRefObject, I {
  public void M1 (R r, SomeClass o) { ... }
}
```

If we create an instance of M in another domain and try to call it:
```
  I obj = (I)otherDomain.CreateInstanceAndUnwrap (typeof(M).Assembly.FullName,
  nameof(M));
  R r;
  r.i = 42;
  SomeClass o = ...;
  obj.M1 (r, o);
```

Mono will need to create a wrapper that can invoke M.M1 in the other domain.
The way the wrapper works in `mono_marshal_get_xappdomain_invoke` is by
creating an array of all the arguments that need to be serialized (see
`mono_get_xdomain_marshal_type`) and then serializing the whole array (by
calling out to `System.Runtime.Remoting.RemotingServices.SerializeCallData`).
In the example it would make a two element array and try to serialize `r` and
`o` into it. For valuetypes it normally does this by boxing the argument.
However since `R` is a ref-struct, boxing it is not allowed.

This works on .NET Framework.

However for Mono we would need to serilize `R` without boxing it, which seems
challenging with our current setup.

So for now we generate a wrapper that just throws a NotImplementedException if
it is ever called.

This fixes #14809 (in that marshalling a
TextWriter across domains works again) but in an unsatisfactory way (because
you can't call any of the ReadOnlySpan<char> overloads on the transparent proxy
object).
marek-safar added a commit that referenced this issue Jun 7, 2019
akoeplinger added a commit that referenced this issue Jun 7, 2019
…f struct args (#14863)

* [AppDomain] Cross-appdomain wrapper throws NIE for methods with ref struct arguments

If we have a ref struct and a method that takes it as an argument:

```
[Serializable]
public ref struct R {
  public int i;
}

public interface I {
  public void M1 (R r, SomeClass o);
}

public class M : MarshalByRefObject, I {
  public void M1 (R r, SomeClass o) { ... }
}
```

If we create an instance of M in another domain and try to call it:
```
  I obj = (I)otherDomain.CreateInstanceAndUnwrap (typeof(M).Assembly.FullName,
  nameof(M));
  R r;
  r.i = 42;
  SomeClass o = ...;
  obj.M1 (r, o);
```

Mono will need to create a wrapper that can invoke M.M1 in the other domain.
The way the wrapper works in `mono_marshal_get_xappdomain_invoke` is by
creating an array of all the arguments that need to be serialized (see
`mono_get_xdomain_marshal_type`) and then serializing the whole array (by
calling out to `System.Runtime.Remoting.RemotingServices.SerializeCallData`).
In the example it would make a two element array and try to serialize `r` and
`o` into it. For valuetypes it normally does this by boxing the argument.
However since `R` is a ref-struct, boxing it is not allowed.

This works on .NET Framework.

However for Mono we would need to serilize `R` without boxing it, which seems
challenging with our current setup.

So for now we generate a wrapper that just throws a NotImplementedException if
it is ever called.

This fixes #14809 (in that marshalling a
TextWriter across domains works again) but in an unsatisfactory way (because
you can't call any of the ReadOnlySpan<char> overloads on the transparent proxy
object).

* [corlib] Add back Serializable attribute on some reflection classes

Tests that use https://www.nuget.org/packages/NUnit.ApplicationDomain/
need to serialize MethodInfo (and hence MethodBase).

* [corlib] Add test for transparent proxies for classes with methods that take
ref struct args

Regression test for #14809

* Bump API snapshot submodule
akoeplinger added a commit that referenced this issue Jun 7, 2019
…ds with ref struct args (#14867)

* [AppDomain] Cross-appdomain wrapper throws NIE for methods with ref struct arguments

If we have a ref struct and a method that takes it as an argument:

```
[Serializable]
public ref struct R {
  public int i;
}

public interface I {
  public void M1 (R r, SomeClass o);
}

public class M : MarshalByRefObject, I {
  public void M1 (R r, SomeClass o) { ... }
}
```

If we create an instance of M in another domain and try to call it:
```
  I obj = (I)otherDomain.CreateInstanceAndUnwrap (typeof(M).Assembly.FullName,
  nameof(M));
  R r;
  r.i = 42;
  SomeClass o = ...;
  obj.M1 (r, o);
```

Mono will need to create a wrapper that can invoke M.M1 in the other domain.
The way the wrapper works in `mono_marshal_get_xappdomain_invoke` is by
creating an array of all the arguments that need to be serialized (see
`mono_get_xdomain_marshal_type`) and then serializing the whole array (by
calling out to `System.Runtime.Remoting.RemotingServices.SerializeCallData`).
In the example it would make a two element array and try to serialize `r` and
`o` into it. For valuetypes it normally does this by boxing the argument.
However since `R` is a ref-struct, boxing it is not allowed.

This works on .NET Framework.

However for Mono we would need to serilize `R` without boxing it, which seems
challenging with our current setup.

So for now we generate a wrapper that just throws a NotImplementedException if
it is ever called.

This fixes #14809 (in that marshalling a
TextWriter across domains works again) but in an unsatisfactory way (because
you can't call any of the ReadOnlySpan<char> overloads on the transparent proxy
object).

* [corlib] Add back Serializable attribute on some reflection classes

Tests that use https://www.nuget.org/packages/NUnit.ApplicationDomain/
need to serialize MethodInfo (and hence MethodBase).

* [corlib] Add test for transparent proxies for classes with methods that take ref struct args

Regression test for #14809

* Bump API snapshot submodule
@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Jun 24, 2019

@marek-safar Is there something more that needs to be done? It looks like it's been fixed everywhere.

jonpryor added a commit to xamarin/xamarin-android that referenced this issue Sep 6, 2019
Changes: http://github.com/mono/mono/compare/2c3aeaf3780de7392a0d3cbe4dcf86846eb4dffa...29b1ac19c961b959a09097dbc0fe4cd567cc5298

	$ git diff --shortstat 2c3aeaf3..29b1ac19
	 1528 files changed, 45421 insertions(+), 21967 deletions(-)

Changes: mono/api-doc-tools@d03e819...5da8127

	$ git diff --shortstat d03e8198..5da8127a
	 1001 files changed, 86168 insertions(+), 11863 deletions(-)

Changes: mono/api-snapshot@e09042d...1ca8e82

	$ git diff --shortstat e09042da..1ca8e82f
        28 files changed, 612 insertions(+), 217 deletions(-)

Changes: mono/cecil@a6c8f5e...cb6c1ca

	$ git diff --shortstat a6c8f5e1..cb6c1ca9
	 13 files changed, 233 insertions(+), 88 deletions(-)

Changes: mono/corefx@4806207...470e0e1

	$ git diff --shortstat 4806207f...470e0e10
	 4 files changed, 31 insertions(+), 12 deletions(-)

Changes: mono/linker@ebe2a1f...1f87de3

	$ git diff --shortstat ebe2a1f4...1f87de35
        90 files changed, 3219 insertions(+), 1224 deletions(-)

Changes: xamarin/java.interop@befdbc0...be6048e

	$ git diff --shortstat befdbc03...be6048ed
        3 files changed, 3 insertions(+), 3 deletions(-)

Upstream-Fixes: https://bugs.winehq.org/show_bug.cgi?id=47561
Upstream-Fixes: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/967582
Upstream-Fixes: dotnet/coreclr#25071
Upstream-Fixes: dotnet/coreclr#25242
Upstream-Fixes: dotnet/coreclr#25632
Upstream-Fixes: dotnet/coreclr#25709
Upstream-Fixes: dotnet/corefx#37955
Upstream-Fixes: dotnet/corefx#38455
Upstream-Fixes: mono/mono#7377
Upstream-Fixes: mono/mono#8747
Upstream-Fixes: mono/mono#9621
Upstream-Fixes: mono/mono#9664
Upstream-Fixes: mono/mono#9706
Upstream-Fixes: mono/mono#10201
Upstream-Fixes: mono/mono#10645
Upstream-Fixes: mono/mono#10748
Upstream-Fixes: mono/mono#10848
Upstream-Fixes: mono/mono#12141
Upstream-Fixes: mono/mono#13311
Upstream-Fixes: mono/mono#13408
Upstream-Fixes: mono/mono#13412
Upstream-Fixes: mono/mono#13891
Upstream-Fixes: mono/mono#13923
Upstream-Fixes: mono/mono#13945
Upstream-Fixes: mono/mono#14170
Upstream-Fixes: mono/mono#14214
Upstream-Fixes: mono/mono#14214
Upstream-Fixes: mono/mono#14215
Upstream-Fixes: mono/mono#14243
Upstream-Fixes: mono/mono#14377
Upstream-Fixes: mono/mono#14495
Upstream-Fixes: mono/mono#14555
Upstream-Fixes: mono/mono#14724
Upstream-Fixes: mono/mono#14729
Upstream-Fixes: mono/mono#14772
Upstream-Fixes: mono/mono#14792
Upstream-Fixes: mono/mono#14793
Upstream-Fixes: mono/mono#14809
Upstream-Fixes: mono/mono#14830
Upstream-Fixes: mono/mono#14839
Upstream-Fixes: mono/mono#14841
Upstream-Fixes: mono/mono#14847
Upstream-Fixes: mono/mono#14864
Upstream-Fixes: mono/mono#14871
Upstream-Fixes: mono/mono#14917
Upstream-Fixes: mono/mono#14945
Upstream-Fixes: mono/mono#14946
Upstream-Fixes: mono/mono#14948
Upstream-Fixes: mono/mono#14957
Upstream-Fixes: mono/mono#14959
Upstream-Fixes: mono/mono#14960
Upstream-Fixes: mono/mono#14961
Upstream-Fixes: mono/mono#14963
Upstream-Fixes: mono/mono#14971
Upstream-Fixes: mono/mono#14972
Upstream-Fixes: mono/mono#14975
Upstream-Fixes: mono/mono#15023
Upstream-Fixes: mono/mono#15048
Upstream-Fixes: mono/mono#15058
Upstream-Fixes: mono/mono#15080
Upstream-Fixes: mono/mono#15182
Upstream-Fixes: mono/mono#15188
Upstream-Fixes: mono/mono#15189
Upstream-Fixes: mono/mono#15261
Upstream-Fixes: mono/mono#15262
Upstream-Fixes: mono/mono#15263
Upstream-Fixes: mono/mono#15265
Upstream-Fixes: mono/mono#15268
Upstream-Fixes: mono/mono#15307
Upstream-Fixes: mono/mono#15324
Upstream-Fixes: mono/mono#15329
Upstream-Fixes: mono/mono#15330
Upstream-Fixes: mono/mono#15441
Upstream-Fixes: mono/mono#15446
Upstream-Fixes: mono/mono#15503
Upstream-Fixes: mono/mono#15541
Upstream-Fixes: mono/mono#15551
Upstream-Fixes: mono/mono#15556
Upstream-Fixes: mono/mono#15596
Upstream-Fixes: mono/mono#15691
Upstream-Fixes: mono/mono#15692
Upstream-Fixes: mono/mono#15740
Upstream-Fixes: mono/mono#15751
Upstream-Fixes: mono/mono#15760
Upstream-Fixes: mono/mono#15781
Upstream-Fixes: mono/mono#15794
Upstream-Fixes: mono/mono#15825
Upstream-Fixes: mono/mono#15853
Upstream-Fixes: mono/mono#15878
Upstream-Fixes: mono/mono#15887
Upstream-Fixes: mono/mono#15990
Upstream-Fixes: mono/mono#16032
Upstream-Fixes: mono/mono#16411
Upstream-Fixes: mono/mono#16486
Upstream-Fixes: https://github.com/mono/mono/issues/25709
Upstream-Fixes: https://github.com/mono/mono/issues/38821
Upstream-Fixes: #3112
Upstream-Fixes: #3168

Update `build-tools/automation/build.groovy` so that it fully cleans
the build tree before starting the build, so that the vestigial mono
submodule (removed in 0c9f83b) is *actually* removed from the build
tree, so that we don't inadvertently use *ancient* submodule contents.
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Sep 6, 2019
Changes: http://github.com/mono/mono/compare/2c3aeaf3780de7392a0d3cbe4dcf86846eb4dffa...29b1ac19c961b959a09097dbc0fe4cd567cc5298

	$ git diff --shortstat 2c3aeaf3..29b1ac19
	 1528 files changed, 45421 insertions(+), 21967 deletions(-)

Changes: mono/api-doc-tools@d03e819...5da8127

	$ git diff --shortstat d03e8198..5da8127a
	 1001 files changed, 86168 insertions(+), 11863 deletions(-)

Changes: mono/api-snapshot@e09042d...1ca8e82

	$ git diff --shortstat e09042da..1ca8e82f
        28 files changed, 612 insertions(+), 217 deletions(-)

Changes: mono/cecil@a6c8f5e...cb6c1ca

	$ git diff --shortstat a6c8f5e1..cb6c1ca9
	 13 files changed, 233 insertions(+), 88 deletions(-)

Changes: mono/corefx@4806207...470e0e1

	$ git diff --shortstat 4806207f...470e0e10
	 4 files changed, 31 insertions(+), 12 deletions(-)

Changes: mono/linker@ebe2a1f...1f87de3

	$ git diff --shortstat ebe2a1f4...1f87de35
	 90 files changed, 3219 insertions(+), 1224 deletions(-)

Changes: xamarin/java.interop@75b1189...4fd3539

	$ git diff --shortstat 75b11891...4fd35393
	 34 files changed, 448 insertions(+), 52 deletions(-)

Upstream-Fixes: https://bugs.winehq.org/show_bug.cgi?id=47561
Upstream-Fixes: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/967582
Upstream-Fixes: dotnet/coreclr#25071
Upstream-Fixes: dotnet/coreclr#25242
Upstream-Fixes: dotnet/coreclr#25632
Upstream-Fixes: dotnet/coreclr#25709
Upstream-Fixes: dotnet/corefx#37955
Upstream-Fixes: dotnet/corefx#38455
Upstream-Fixes: mono/mono#7377
Upstream-Fixes: mono/mono#8747
Upstream-Fixes: mono/mono#9621
Upstream-Fixes: mono/mono#9664
Upstream-Fixes: mono/mono#9706
Upstream-Fixes: mono/mono#10201
Upstream-Fixes: mono/mono#10645
Upstream-Fixes: mono/mono#10748
Upstream-Fixes: mono/mono#10848
Upstream-Fixes: mono/mono#12141
Upstream-Fixes: mono/mono#13311
Upstream-Fixes: mono/mono#13408
Upstream-Fixes: mono/mono#13412
Upstream-Fixes: mono/mono#13891
Upstream-Fixes: mono/mono#13923
Upstream-Fixes: mono/mono#13945
Upstream-Fixes: mono/mono#14170
Upstream-Fixes: mono/mono#14214
Upstream-Fixes: mono/mono#14214
Upstream-Fixes: mono/mono#14215
Upstream-Fixes: mono/mono#14243
Upstream-Fixes: mono/mono#14377
Upstream-Fixes: mono/mono#14495
Upstream-Fixes: mono/mono#14555
Upstream-Fixes: mono/mono#14724
Upstream-Fixes: mono/mono#14729
Upstream-Fixes: mono/mono#14772
Upstream-Fixes: mono/mono#14792
Upstream-Fixes: mono/mono#14793
Upstream-Fixes: mono/mono#14809
Upstream-Fixes: mono/mono#14830
Upstream-Fixes: mono/mono#14839
Upstream-Fixes: mono/mono#14841
Upstream-Fixes: mono/mono#14847
Upstream-Fixes: mono/mono#14864
Upstream-Fixes: mono/mono#14871
Upstream-Fixes: mono/mono#14917
Upstream-Fixes: mono/mono#14945
Upstream-Fixes: mono/mono#14946
Upstream-Fixes: mono/mono#14948
Upstream-Fixes: mono/mono#14957
Upstream-Fixes: mono/mono#14959
Upstream-Fixes: mono/mono#14960
Upstream-Fixes: mono/mono#14961
Upstream-Fixes: mono/mono#14963
Upstream-Fixes: mono/mono#14971
Upstream-Fixes: mono/mono#14972
Upstream-Fixes: mono/mono#14975
Upstream-Fixes: mono/mono#15023
Upstream-Fixes: mono/mono#15048
Upstream-Fixes: mono/mono#15058
Upstream-Fixes: mono/mono#15080
Upstream-Fixes: mono/mono#15182
Upstream-Fixes: mono/mono#15188
Upstream-Fixes: mono/mono#15189
Upstream-Fixes: mono/mono#15261
Upstream-Fixes: mono/mono#15262
Upstream-Fixes: mono/mono#15263
Upstream-Fixes: mono/mono#15265
Upstream-Fixes: mono/mono#15268
Upstream-Fixes: mono/mono#15307
Upstream-Fixes: mono/mono#15324
Upstream-Fixes: mono/mono#15329
Upstream-Fixes: mono/mono#15330
Upstream-Fixes: mono/mono#15441
Upstream-Fixes: mono/mono#15446
Upstream-Fixes: mono/mono#15503
Upstream-Fixes: mono/mono#15541
Upstream-Fixes: mono/mono#15551
Upstream-Fixes: mono/mono#15556
Upstream-Fixes: mono/mono#15596
Upstream-Fixes: mono/mono#15691
Upstream-Fixes: mono/mono#15692
Upstream-Fixes: mono/mono#15740
Upstream-Fixes: mono/mono#15751
Upstream-Fixes: mono/mono#15760
Upstream-Fixes: mono/mono#15781
Upstream-Fixes: mono/mono#15794
Upstream-Fixes: mono/mono#15825
Upstream-Fixes: mono/mono#15853
Upstream-Fixes: mono/mono#15878
Upstream-Fixes: mono/mono#15887
Upstream-Fixes: mono/mono#15990
Upstream-Fixes: mono/mono#16032
Upstream-Fixes: mono/mono#16411
Upstream-Fixes: mono/mono#16486
Upstream-Fixes: https://github.com/mono/mono/issues/25709
Upstream-Fixes: https://github.com/mono/mono/issues/38821
Upstream-Fixes: xamarin#3112
Upstream-Fixes: xamarin#3168

Update `build-tools/automation/build.groovy` so that it fully cleans
the build tree before starting the build, so that the vestigial mono
submodule (removed in 0c9f83b) is *actually* removed from the build
tree, so that we don't inadvertently use *ancient* submodule contents.
jonpryor added a commit to xamarin/xamarin-android that referenced this issue Sep 7, 2019
Changes: http://github.com/mono/mono/compare/2c3aeaf3780de7392a0d3cbe4dcf86846eb4dffa...29b1ac19c961b959a09097dbc0fe4cd567cc5298

	$ git diff --shortstat 2c3aeaf3..29b1ac19
	 1528 files changed, 45421 insertions(+), 21967 deletions(-)

Changes: mono/api-doc-tools@d03e819...5da8127

	$ git diff --shortstat d03e8198..5da8127a
	 1001 files changed, 86168 insertions(+), 11863 deletions(-)

Changes: mono/api-snapshot@e09042d...1ca8e82

	$ git diff --shortstat e09042da..1ca8e82f
        28 files changed, 612 insertions(+), 217 deletions(-)

Changes: mono/cecil@a6c8f5e...cb6c1ca

	$ git diff --shortstat a6c8f5e1..cb6c1ca9
	 13 files changed, 233 insertions(+), 88 deletions(-)

Changes: mono/corefx@4806207...470e0e1

	$ git diff --shortstat 4806207f...470e0e10
	 4 files changed, 31 insertions(+), 12 deletions(-)

Changes: mono/linker@ebe2a1f...1f87de3

	$ git diff --shortstat ebe2a1f4...1f87de35
	 90 files changed, 3219 insertions(+), 1224 deletions(-)

Changes: xamarin/java.interop@75b1189...4fd3539

	$ git diff --shortstat 75b11891...4fd35393
	 34 files changed, 448 insertions(+), 52 deletions(-)

Fixes: #3112
Fixes: #3168

Context: https://bugs.winehq.org/show_bug.cgi?id=47561
Context: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/967582
Context: dotnet/coreclr#25071
Context: dotnet/coreclr#25242
Context: dotnet/coreclr#25632
Context: dotnet/coreclr#25709
Context: dotnet/corefx#37955
Context: dotnet/corefx#38455
Context: mono/mono#7377
Context: mono/mono#8747
Context: mono/mono#9621
Context: mono/mono#9664
Context: mono/mono#9706
Context: mono/mono#10201
Context: mono/mono#10645
Context: mono/mono#10748
Context: mono/mono#10848
Context: mono/mono#12141
Context: mono/mono#13311
Context: mono/mono#13408
Context: mono/mono#13412
Context: mono/mono#13891
Context: mono/mono#13923
Context: mono/mono#13945
Context: mono/mono#14170
Context: mono/mono#14214
Context: mono/mono#14214
Context: mono/mono#14215
Context: mono/mono#14243
Context: mono/mono#14377
Context: mono/mono#14495
Context: mono/mono#14555
Context: mono/mono#14724
Context: mono/mono#14729
Context: mono/mono#14772
Context: mono/mono#14792
Context: mono/mono#14793
Context: mono/mono#14809
Context: mono/mono#14830
Context: mono/mono#14839
Context: mono/mono#14841
Context: mono/mono#14847
Context: mono/mono#14864
Context: mono/mono#14871
Context: mono/mono#14917
Context: mono/mono#14945
Context: mono/mono#14946
Context: mono/mono#14948
Context: mono/mono#14957
Context: mono/mono#14959
Context: mono/mono#14960
Context: mono/mono#14961
Context: mono/mono#14963
Context: mono/mono#14971
Context: mono/mono#14972
Context: mono/mono#14975
Context: mono/mono#15023
Context: mono/mono#15048
Context: mono/mono#15058
Context: mono/mono#15080
Context: mono/mono#15182
Context: mono/mono#15188
Context: mono/mono#15189
Context: mono/mono#15261
Context: mono/mono#15262
Context: mono/mono#15263
Context: mono/mono#15265
Context: mono/mono#15268
Context: mono/mono#15307
Context: mono/mono#15324
Context: mono/mono#15329
Context: mono/mono#15330
Context: mono/mono#15441
Context: mono/mono#15446
Context: mono/mono#15503
Context: mono/mono#15541
Context: mono/mono#15551
Context: mono/mono#15556
Context: mono/mono#15596
Context: mono/mono#15691
Context: mono/mono#15692
Context: mono/mono#15740
Context: mono/mono#15751
Context: mono/mono#15760
Context: mono/mono#15781
Context: mono/mono#15794
Context: mono/mono#15825
Context: mono/mono#15853
Context: mono/mono#15878
Context: mono/mono#15887
Context: mono/mono#15990
Context: mono/mono#16032
Context: mono/mono#16411
Context: mono/mono#16486
Context: https://github.com/mono/mono/issues/25709
Context: https://github.com/mono/mono/issues/38821

Update `build-tools/automation/build.groovy` so that it fully cleans
the build tree before starting the build, so that the vestigial mono
submodule (removed in 0c9f83b) is *actually* removed from the build
tree, so that we don't inadvertently use *ancient* submodule contents.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.