Bug 57661 - ExecutionEngineException "Attempting to JIT compile method" when assigning delegate class
Summary: ExecutionEngineException "Attempting to JIT compile method" when assigning de...
Status: RESOLVED NORESPONSE
Alias: None
Product: iOS
Classification: Xamarin
Component: Mono runtime / AOT compiler ()
Version: XI 10.10 (d15-2)
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Future Cycle (TBD)
Assignee: Zoltan Varga
URL:
Depends on:
Blocks:
 
Reported: 2017-06-21 11:40 UTC by Alexander Melchers
Modified: 2017-08-08 23:35 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NORESPONSE

Description Alexander Melchers 2017-06-21 11:40:20 UTC
## PROBLEM DESCRIPTION
With the latest build of our App I've encountered the following exception, which originates from a bindings-project we've associated with our App as a NuGet-package:

System.ExecutionEngineException: Attempting to JIT compile method 'My.Bindings.Project.Class:set_WeakDelegate (Foundation.NSObject)' while running in aot-only mode. See https://developer.xamarin.com/guides/ios/advanced_topics/limitations/ for more information.

The exception indeed occurs on a line of code in our bindings-project where a delegate class is assigned to the 'Delegate'-property of the 'SharedInstance' of the bound SDK. The bindings themselves were created using Objective Sharpie and are known to have worked, as previous versions of the SDK used the same bindings (verified) and do not exhibit this issue.

Said delegate class is used to listen to events coming from the bound SDK, and is itself defined in as part of the linked framework (i.e., just like the static SDK class that discloses the 'SharedInstance', the delegate class is defined in the ApiDefinitions). Within the API, it is defined as an interface, annotated using the 'Internal', 'Protocol', 'Model', and 'BaseType(typeof(NSObject))' attributes. Our custom code within the bindings-project defines a class that inherits from the former interface/class and overrides its inherited callback-methods (each defined in ApiDefinitions using the 'Abstract' and 'Export' annotations) to trigger C#-style events.

We then use this newly created delegate class from within another class, central to the library, that accesses the bound SDK's 'SharedInstance'-singleton and sets its delegate, so that the delegate class itself may remain internal to the library, but its events may be propagated.

## EXAMPLE CODE
Unfortunately, the code behind the bindings-project is non-disclosable (not even in a private bug report), so that I have reproduced a highly simplified version of it below:

==ApiDefinitions.cs==
namespace My.Bindings.Project
{
  [Internal]
  [BaseType(typeof(NSObject))]
  interface SdkInterface
  {
    [Static]
    [Export("sharedInstance")]
    SdkInterface SharedInstance { get; }
  }
  
  [Internal]
  [Protocol, Model]
  [BaseType(typeof(NSObject))]
  interface Delegate
  {
    [Abstract]
    [Export("sdk:customEvent:")]
    void CustomEvent(SdkInterface sdkInterface, NSDictionary values);
  }
}

==SdkEventListener.cs==
namespace My.Bindings.Project
{
  internal class SdkEventListener : Delegate
  {
    public event EventHandler<CustomEventArgs> Event;
    
    public override void CustomEvent(SdkInterface sdkInterface, NSDictionary values)
      => this.Event?.Invoke(this, new CustomEventArgs(values));
  }
}

==SdkManager.cs==
namespace My.Bindings.Project
{
  public class SdkManager : SdkInterface
  {
    public event EventHandler<CustomEventArgs> Event;
    
    private SdkInterface Sdk { get; }
    
    private SdkEventListener Listener => (SdkEventListener) this.Sdk.Delegate;
    
    public SdkManager()
    {
      this.Sdk = SdkInterface.SharedInstance;
      this.Sdk.Delegate = new SdkEventListener();
      this.Listener.Event += this.OnSdkEvent;
    }
    
    protected virtual void OnSdkEvent(object sender, CustomEventArgs e)
      => this.Event?.Invoke(this, e);
  }
}

## ENVIRONMENT
Our main development environment consists of Visual Studio Professional 2015 (version 14.0.25431.01) Update 3 running on Windows against a VSTS Mac-agent for building iOS-projects. However, this problem also (or, rather, actually) occurs on our Mac build machine, on which we run our secondary development environment, more pertinent to the call:

* Visual Studio Community 2017 for Mac
  Version 7.0.1 (build 24)
  Runtime: Mono 5.0.1.1 (2017-02/5077205) (64-bit), GTK+ 2.24.23
* NuGet
  Version: 4.0.0.2323
* .NET Core
* Apple Developer Tools
  Xcode 8.2 (11766)
  Build 8C38
* Xamarin.Mac
  Version: 3.4.0.36 (Visual Studio Community)
* Xamarin.iOS
  Version: 10.10.0.36 (Visual Studio Community)
  Branch: d15-2
  Build date: 2017-05-22 16:30:53-0400
* Operating System
  Mac OS X 10.12.5
  Darwin 16.6.0 Darwin Kernel Version 16.6.0
    Fri Apr 14 16:21:16 PDT 2017

This is run next to our old Xamarin Studio installation:

* Xamarin Studio Community
  Version 6.3 (build 864)
  Runtime: Mono 5.0.1.1 (2017-02/5077205) (64-bit), GTK+ 2.24.23
* NuGet
  Version: 3.5.0.0
* Apple Developer Tools
  Xcode 8.2 (11766)
  Build 8C38
* Xamarin.iOS
  Version: 10.10.0.36 (Xamarin Studio Community)
  Branch: d15-2
  Build date: 2017-05-22 16:30:53-0400
* Xamarin.Mac
  Version: 3.4.0.36 (Xamarin Studio Community)
* Operating System
  Mac OS X 10.12.5
  Darwin 16.6.0 Darwin Kernel Version 16.6.0
    Fri Apr 14 16:21:16 PDT 2017

Both our App and the NuGet-package are build to "Link Framework SDKs Only".

## WHAT HAS BEEN TRIED
1. Verified that the previous build of the NuGet-package incorporating an older version of the SDK does not exhibit the reported bug.
2. Downloaded a new version of the SDK and verified that it too results in the bug.
3. Rebuilt the over NuGet-package (i.e. older SDK-version) and verified that it now triggers the bug as well.
4. Verified that the bug has existed at least from the 7th of June by running an older build of our App from TestFlight.
5. Verified if a recent upgrade of Xamarin.Forms from version 2.3.4.231 to 2.3.4.247 has no influence on the bug appearing.
6. Verified that making private property 'SdkManager.Sdk' from the sample code above static makes no difference to the bug appearing.
7. Verified that setting the App-project's linker behaviour to "Link All" makes no difference, and rather results in a unhandled exception occurring even before the point where the ExecutionEngineException would otherwise have occurred.
8. Setting the App-project's linker behaviour to "Don't Link" results in the following compile-time error:

This version of Xamarin.iOS requires the iOS 10.3 SDK (shipped with Xcode 8.3). Either upgrade Xcode to get the required header files or set the managed linker behaviour to Link Framework SDKs Only (to try to avoid the new APIs).

Updating Xcode is not currently an option, however, as we use `Apple App Store Release`-task from our VSTS (Team Build) 2015 server, which depends on tooling that has become obsolete in newer versions of Xcode.

Thanks in advance for the help!
Comment 1 Alexander Melchers 2017-06-21 13:51:44 UTC
As additional information, setting the Foundation.PreserveAttribute on the above 'SdkEventListener'-class does not resolve the problem either.
Comment 2 Alex Soto [MSFT] 2017-06-21 19:13:35 UTC
Hello, this looks very similar to Bug #53872 but before I mark this as a duplicate I would like to have some information from you. Can you try the following?

Option a:
Select 

"Project Options->compiler/Enable optimizations[Visual Stdio for Mac]" [1]
"Project Options->Buils/Optimize Code[Visual Studio on Windows]" [1] 

on the compiler (csc Windows) this should workaround the issue.

[1] `/optimize+` on the command line

Option b:
Update to our beta channel Xamarin.iOS 10.12.0.5 or greater should have a fix and the workaround (option a) should no longer be needed.

Let me know if any of the above options works for you.
Comment 3 Alexander Melchers 2017-06-22 14:22:45 UTC
Hello Alex,

Thanks for your response! B is not an option for us, as we need to stay on the stable track on our build server. However, I have tried A in various configurations:

* In VS2015 on Windows with code optimization turned on for just the project, just the NuGet, and both.
* In Xamarin Studio and Visual Studio on Mac with code optimization turned on for just the project, just the NuGet, and both.

Interestingly, all tried combinations result in the ExecutionEngineException when run within VS2015 on Windows. I did manage a minor break-through when using code optimization on the NuGet-/bindings-project from within either Xamarin Studio or Visual Studio on the Mac, however, in which case it does not seem to matter whether code optimization is turned on for the final project or not.

Turning on code optimization for the NuGet-/bindings-project, building it through the Mac build-agent, and then running the final project from within Xamarin Studio (or VS Mac) results in the final project starting up and running without problems. However, the SDK wrapped within the NuGet-package no longer seems to function. That is, the events that I would expect to receive from the SDK are not being received. As these events originate with the delegate mentioned in my original problem description, my first thoughts are that the assignment of the delegate class might no longer cause an exception, but is still not entirely successful.

Please let me know if there is anything else we might be able to try, though it might be an option for us to wait for the Xamarin.iOS 10.12.0.5 beta to get into stable. Any idea of the time frame for that to happen?

Thanks again for the help!
Comment 4 Alexander Melchers 2017-06-22 14:39:16 UTC
Hi Alex,

Something else I've been considering is that the problem with the final project being able to run if the binding-project is compiled with code optimization might actually lie with the SDK itself. That is, the SDK comes with instructions stating that ENABLE_BITCODE should be set to NO (within Xcode context). Could it be that this is what code optimization does, making the observed behaviour the expected?
Comment 5 Alex Soto [MSFT] 2017-06-22 17:22:09 UTC
Ahh don't worry we do handle the bitcode set to no by default for iOS projects, the X.I  10.12 should become stable sometime in July. That said is there any way for you to test if X.I 10.12 does solve your issue? I do not want you to have a bad surprise
Comment 6 Alexander Melchers 2017-06-27 14:14:46 UTC
Hello Alex,

We're considering whether we could use one of our MacBook's with Xamarin Studio to check whether Xamarin.iOS 10.12.0.5 might solve the problem for us. It would be good, however, if, after checking this, we could roll Xamarin.iOS back to the latest stable version and get back onto the stable track. Is this possible (how does one do this)?
Comment 7 Alex Soto [MSFT] 2017-06-27 15:49:29 UTC
Absolutely, all you have to do is VisualStudio Menu > check for updates then you just select the channel you want to be Alpha | Beta | Stable, you can select any of the channels at any time to switch between them.

Cheers!
Comment 8 Alexander Melchers 2017-07-03 14:39:19 UTC
Hi Alex,

Sorry for delay in response - other matters required my attention over the past couple of days. However, I've since switched our MacBook to the beta-track to see whether this might resolve our problems. That is, I switched track, though the only package I updated is Xamarin.iOS, which I upgraded to version 10.12.0.5 as per your recommendation. The result, however, is the same as described on 2017-06-22 above (i.e. option A in your original response). That is, I still get the exception when running from Windows, and get an application that appears to work but actually doesn't when running from Mac.

Is there anything else I could try?

All the best,
Alexander.
Comment 9 Alex Soto [MSFT] 2017-07-06 20:38:18 UTC
Unfortunately, at this point without a test case, there is no way we can reproduce and/or debug this issue on our end. I would recommend trying to replicate your issue with another binding that you can actually submit to us. There are some public repositories[1] where you can pick some already bound libraries and maybe create a small test case from there. From the pattern you describe a delegate that you can create your own custom events maybe this binding might be an easy fit to create a test case [2].

[1]:
https://github.com/xamarin/XamarinComponents
https://github.com/mono/monotouch-bindings

[2]:
https://github.com/xamarin/XamarinComponents/tree/master/iOS/MBProgressHUD
Comment 10 Vincent Dondain [MSFT] 2017-08-08 23:35:57 UTC
We have not received the requested information. If you are still experiencing this issue please provide all the requested information and re-open the bug report. Thanks!