We need a way to represent a managed object in native code, and since most our existing
runtime code uses MonoObjects, we use the same for the CoreCLR bridge, just our own
version of it. In Mono, the MonoObjects are tracked by the GC (which scans the stack),
but we can't make CoreCLR scan the stack, so we use a reference counted version of
MonoObject instead - we just put the GCHandle into a reference counted MonoObject,
and when the MonoObject is freed, then we free the GCHandle as well.
* Move the existing logic to call Runtime.Initialize into the MonoVM code.
* Implement calling the managed Runtime.Initialize method from the CoreCLR bridge.
The call to Runtime.Initialize succeeds, which means we're now executing
managed code with CoreCLR for the first time.
This test verifies that the build log prints:
"execution started with arguments: actool --errors --warnings --notices --output-format xml1 --output-partial-info-plist "
However, for M1 machines, we don't call actool directly, we go through 'arch'
instead, and this line is printed:
Tool arch execution started with arguments: -arch arm64e /usr/bin/xcrun actool --errors --warnings --notices --output-format xml1 --output-partial-info-plist ...
So adjust the test to cope with both of these behaviors.
* [mono] Bump mono to bring iOS binaries built with xcode12.4
Also bumping system mono pkg to the one that contains arm64 support
New commits in mono/mono:
* mono/mono@eb4c3116eb Build iOS SDK archives on Xcode 12.4
* mono/mono@acb8d8ed6f [2020-02][marshal] Fix VARIANT and BSTR marshaling in structs (#20918)
Diff: be9218f4d1..eb4c3116eb
* [mtouch] fix version logic check
Fixes Unexpected minOS version (expected 8.0.0, found 7.0.0) in MonoTouch.iphonesimulator.sdk/lib/libmono-native-compat.dylib ()
we really only care if it is over the version we expect not below.
* Fix version test
* Bump to .NET 6.0.100-preview.3.21152.10
* Bump to 6.0.100-preview.3.21152.10.
* Bump to 6.0.100-preview.3.21161.7.
* Bump to .NET 6.0.100-preview.3.21161.23.
* [dotnet-linker] Bump ILink and use the supported method of getting an assembly's location.
* Bump to MSBuild.StructuredLogger 2.1.364 to get support for newer binlog versions.
* Fix build failure
Fixes:
TestHelpers/BuildEngine.cs(161,24): error CS0433: The type 'ProjectEvaluationFinishedEventArgs' exists in both 'Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'StructuredLogger, Version=2.1.0.0, Culture=neutral, PublicKeyToken=d4c7181801cb6448' [/Users/builder/azdo/_work/1/s/xamarin-macios/tests/msbuild/Xamarin.MacDev.Tests/Xamarin.MacDev.Tests.csproj]
* Update parsing binlog properties.
* Be more defensive.
* [tests] Make sure the InternalsVisibleToAttribute constructor isn't linked away.
* [tests] Implement better printing of binlogs.
The latest MSBuild.StructuredLogger made some internal changes to the Message
property which confuses some of our test logic. So implement manual printing
of the log entries that we care about to make sure they conform to the
expected format by the tests (the output is mimicing what 'msbuild /v:diag
foo.binlog' would show).
* [ObjCRuntime] Simplify Runtime.NSLog to always call xamarin_log.
This also fixes a couple of bugs:
* We wouldn't use the arm64 version of NSLog on Xamarin.Mac.
* We would use a wrong xamarin_log declaration on Xamarin.Mac on older macOS
(the string argument would be UTF8 as opposed to Unicode, which is what the
native function expects).
* [Dlfcn] Ignore any failures to show a warning about dlopen with full path.
We can run into this problem:
System.EntryPointNotFoundException: xamarin_log assembly:<unknown assembly> type:<unknown type> member:(null)
at (wrapper managed-to-native) ObjCRuntime.Runtime.xamarin_log(string)
at ObjCRuntime.Runtime.NSLog (System.String value) [0x00001] in <7b41a16d434f401091abbf1beafe6453>:0
at ObjCRuntime.Dlfcn.dlopen (System.String path, System.Int32 mode) [0x0003b] in <7b41a16d434f401091abbf1beafe6453>:0
at ObjCRuntime.Runtime.LookupInternalFunction[T] (System.String name) [0x00040] in <7b41a16d434f401091abbf1beafe6453>:0
at ObjCRuntime.Runtime.EnsureInitialized () [0x00036] in <7b41a16d434f401091abbf1beafe6453>:0
at AppKit.NSApplication.Init () [0x00016] in <7b41a16d434f401091abbf1beafe6453>:0
at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:395
which happens because we're trying to find libxammac.dylib, which we first try
to load without a full path, which runs into a code path that wants to show a
warning, which wants to use xamarin_log, which is in libxammac.dylib, which
we're trying to load. Ops.
So just ignore any failures to print this warning.
* Find a solution that doesn't involve catching exceptions.
The fields of the MonoObject struct is specific to MonoVM, so this makes sure
we don't accidentally poke into random memory on CoreCLR.
Co-authored-by: TJ Lambert <50846373+tj-devel709@users.noreply.github.com>
If no exception handling is provided when calling a managed delegate from native
code, and the managed code throws, then we'll abort.
It's not entirely clear how we'll handle managed exceptions that go through native
code yet, so this makes the initial implementation easier. By making the exception
handling optional, it'll be easy to find all cases where we need to fix it later,
by making it non-optional. The alternative is to add exception handling code all
over the place that would potentially have to be updated when we figure out exactly
what needs to be done.
This is an interesting issue that happens in the following scenario:
1. A request is performed that will take some extra time to get a
response or an error.
2. The request is cancelled BEFORE the delegate methods
DidReceiveResponse, DidReceiveData or DidCompleteWithError and
called. Yet we have not yet fully canceled the native request. It
does take some time to do so, that is why we have a
'NSURLSessionTaskStateCanceling' and not 'NSURLSessionTaskStateCancelled'
The issue happens because the GetInflightData checks if the task has
been canceled. In that method we have the following:
```csharp
if (inflight.CancellationToken.IsCancellationRequested)
task?.Cancel ();
return inflight;
```
The call of the Cancel method in the NSData task has as ripple effect which
is the execution of the following callback:
```csharp
cancellationToken.Register (() => {
RemoveInflightData (dataTask);
tcs.TrySetCanceled ();
});
```
Which calls:
```csharp
void RemoveInflightData (NSUrlSessionTask task, bool cancel = true)
{
lock (inflightRequestsLock) {
if (inflightRequests.TryGetValue (task, out var data)) {
if (cancel)
data.CancellationTokenSource.Cancel ();
data.Dispose ();
inflightRequests.Remove (task);
}
// do we need to be notified? If we have not inflightData, we do not
if (inflightRequests.Count == 0)
RemoveNotification ();
}
if (cancel)
task?.Cancel ();
task?.Dispose ();
}
```
The above call does call Dispose and Dipose in the inflight data does:
```csharp
if (disposing) {
if (CancellationTokenSource != null) {
CancellationTokenSource.Dispose ();
CancellationTokenSource = null;
}
}
```
If we follow these set of events for example in the
DidRecieveResponse:
```chsarp
[Preserve (Conditional = true)]
public override void DidReceiveResponse (NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
{
var inflight = GetInflightData (dataTask);
if (inflight == null)
return;
try {
var urlResponse = (NSHttpUrlResponse)response;
var status = (int)urlResponse.StatusCode;
var content = new NSUrlSessionDataTaskStreamContent (inflight.Stream, () => {
if (!inflight.Completed) {
dataTask.Cancel ();
}
inflight.Disposed = true;
inflight.Stream.TrySetException (new ObjectDisposedException ("The content stream was disposed."));
sessionHandler.RemoveInflightData (dataTask);
}, inflight.CancellationTokenSource.Token);
```
If can happen that, when we get the delegate call to the method, the
request has been cancelled. That means that we are in the precise state
in which we do not longer care about the response BUT we did get a
infligh data reference.. that HAS BEEN DIPOSED!!! this later gives a NRE
in several places.
The correct way is to return null from the GetInflighData method if we
have been cancelled, this makes sense because if we cancelled we do not
care about the execution of any of the methods that required the data
since it has been disposed!
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
Xamarin.MacCatalyst ships a `Xamarin.iOS.dll` assembly that contains
forwarders (to `Xamarin.MacCatalyst.dll`) and stubs that throws
`PlatformNotSupportedException`.
This is used to help code compatibility between both platforms - but
that requires exposing an identical surface and the best way to ensure
this is to compare (and report) them using `apidiff`
Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
We need to call coreclr_initialize/monovm_initialize at startup, so do that.
This is a partial implementation, in that we're not setting all the properties
that we should, and also the PINVOKE_OVERRIDE callback is not doing everything
it should either yet.
Ref: #10504.
Backport several fixes in the CI into xcode12.5 to be able to do the
following:
- Get device tests.
- Get older mac executions.
Includes a needed bump of maccore:
* [d16-9] [CI] remove login keychain password and xqa cert passwords (#2410)