Bug 30488 - [XI 8.10.1] "Error setting up QueryLanguage class vtable" during AOT of Rx-Linq assembly, related to the linker removing certain methods from the QueryLanguage class
Summary: [XI 8.10.1] "Error setting up QueryLanguage class vtable" during AOT of Rx-Li...
Status: VERIFIED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: XI 8.10
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2015-05-26 23:46 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2015-08-13 23:52 UTC (History)
5 users (show)

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


Attachments
Test case (11.01 KB, application/zip)
2015-05-26 23:46 UTC, Brendan Zagaeski (Xamarin Team, assistant)
Details
Diagnostic build output and version info (12.17 KB, application/zip)
2015-05-26 23:47 UTC, Brendan Zagaeski (Xamarin Team, assistant)
Details


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:
VERIFIED FIXED

Description Brendan Zagaeski (Xamarin Team, assistant) 2015-05-26 23:46:40 UTC
Created attachment 11350 [details]
Test case

[XI 8.10.1] "Error setting up QueryLanguage class vtable" during AOT of Rx-Linq assembly because the linker removes the QueryLanguage class


I am not certain that this error should _not_ require user intervention. (Presumably the "System.Reactive.Linq" assembly has _not_ been audited by its authors for compatibility with the Xamarin.iOS linker.) But I also did not find any existing documentation about how to resolve this error message. If nothing else this bug report can serve as some small documentation about the error message.




## Regression status: technically it's a regression in XI 8.10.1 compared to 8.10.0, but it's a slightly unusual case.


The specific error message _itself_ is new [1] in XI 8.10.1 compared to XI 8.10.0.267 (6481535).

> [1] https://github.com/mono/mono/commit/e5678fa983d8b01d2ba5f91bcee364e42b0feea9


But perhaps that error message is simply exposing a case that _failed silently_ before XI 8.10.1?




## Steps to reproduce

Attempt to build the attached test case in the "Release|iPhone" configuration.


### About the test case

The test case is just a template iOS project with the following changes:

- Set the linker to link all assemblies in the Release configuration.

- Add the Rx-Linq NuGet package. 

- Add a few lines to set up a call to the following extension method:
> System.Reactive.Linq.Observable.Repeat<T>(this IObservable<T> source)




## Results

The AOT step fails because the "QueryLanguage" class is missing:


### Excerpts from the diagnostic build output

>   AOT Compilation exited with code 134, command:

>   Mono Ahead of Time compiler - compiling assembly /private/tmp/UnifiedSingleViewIphone1/UnifiedSingleViewIphone1/obj/iPhone/Release/mtouch-cache/64/Build/System.Reactive.Linq.dll
>   Error setting up QueryLanguage class vtable
 		
> MTOUCH: error MT3001: Could not AOT the assembly '/private/tmp/UnifiedSingleViewIphone1/UnifiedSingleViewIphone1/obj/iPhone/Release/mtouch-cache/64/Build/System.Reactive.Linq.dll'




## Workaround

Tell the linker to preserve the "System.Reactive.Linq.QueryLanguage" type. For example, use the included `linker.xml` file that preserves that type by adding the following under "Project options -> iOS Build -> Additional mtouch arguments" :

--xml=${ProjectDir}/linker.xml




## Version information (brief)

Xamarin.iOS 8.10.1.59 (13d1cdc)
Mono 4.0.1 (detached/11b5830)

Xcode 6.3.1 (7703), Build 6D1002
Comment 1 Brendan Zagaeski (Xamarin Team, assistant) 2015-05-26 23:47:27 UTC
Created attachment 11351 [details]
Diagnostic build output and version info
Comment 3 Brendan Zagaeski (Xamarin Team, assistant) 2015-05-27 00:30:28 UTC
## More precise workaround

In case it might be helpful in diagnosing the underlying issue, I just found that you only need to preserve the "Repeat" methods within the "QueryLanguage" class.

<linker>
  <assembly fullname="System.Reactive.Linq">
    <type fullname="System.Reactive.Linq.QueryLanguage">
      <method name="Repeat" />
    </type>
  </assembly>
</linker>




## Additional observation

The "QueryLanguage" class _does exist_ in the "bad" linked version of "System.Reactive.Linq.dll" that is produced by the test case (when you haven't added the `linker.xml` workaround). But the class only contains the `.ctor` method.




## "True" regression status: NOT a recent regression

If you attempt to _run_ the attached test case on 8.10.0.267 (6481535) or 8.9.1.3 (f7736a4), then rather than hitting an AOT error at _build time_, you will instead hit an AOT error at _run time_:

> Attempting to JIT compile method 'System.Reactive.Linq.Observable:.cctor ()'
> while running with --aot-only


You can use exactly the same "more precise workaround" to stop this run time AOT error.
Comment 5 Sebastien Pouliot 2015-05-27 10:16:03 UTC
The issue is that the project configuration (Release/iPhone) is using "Link all assemblies", not the default "Link SDK", setting.

That settings means the developer is responsible to ensure all non-SDK assemblies are safe to be linked. E.g. the static analyzer cannot predict reflection usage in assemblies.

Since Xamarin do not ship System.Reactive.Linq.dll (this is not SDK code) then your workaround is correct and required for "Link all assemblies". Using "Link SDK" (default) works correctly.
Comment 9 Mohit Kheterpal 2015-06-24 09:48:45 UTC
I am able to reproduce this issue with the help of test case provided in comment 0 and observed that this issue is fixed in C5SR2 build i.e. X.iOS 8.10.2.37.

Hence closing this issue.
Comment 10 Kent 2015-08-13 20:28:17 UTC
Finally got my app in a state where I can test this. I originally submitted this problem to Xamarin support via email and communicated with Brendan there.

My original use case is not actually fixed. I'm using latest stable (8.10.4.0) to test. If I don't include this in my linker config:

<assembly fullname="System.Reactive.Linq">
    <type fullname="System.Reactive.Linq.QueryLanguage">
        <method name="Repeat" />
    </type>
</assembly>

Then my application crashes on startup with this output in the iOS Device Log:

ug 14 09:54:29 Kents-iPad MyApp[5245] <Warning>: Unhandled managed exception:
An exception was thrown by the type initializer for System.Reactive.Linq.Observable (System.TypeInitializationException)
at MyApp.Services.Logger.LoggerService.get_Entries () [0x00000] in <filename unknown>:0
at MyApp.Services.Logger.LogFileSink..ctor (ILoggerService loggerService, System.IO.Stream outputStream, System.Func`1 getInputStream) [0x00000] in <filename unknown>:0
at MyApp.UI.iOS.AppDelegate.RegisterLogging (TinyIoC.TinyIoCContainer container) [0x00000] in <filename unknown>:0
at MyApp.UI.iOS.AppDelegate.InitializeIoc () [0x00000] in <filename unknown>:0
at MyApp.UI.iOS.AppDelegate.FinishedLaunching (UIKit.UIApplication app, Foundation.NSDictionary options) [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00000] in <filename unknown>:0
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00000] in <filename unknown>:0
at MyApp.UI.iOS.Application.Main (System.String[] args) [0x00000] in <filename unknown>:0
--- inner exception ---
Attempting to JIT compile method 'System.Reactive.Linq.Observable:.cctor ()' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.
(System.ExecutionEngineException)
(null)

Can this ticket be re-opened please?
Comment 11 Brendan Zagaeski (Xamarin Team, assistant) 2015-08-13 23:47:17 UTC
@Kent, that is the correct intended behavior. 

As mentioned in comment 0:

> the "System.Reactive.Linq" assembly has _not_ been audited by its
> authors for compatibility with the Xamarin.iOS linker

Correspondingly, the fact that an "Attempting to JIT compile method" error appears at run time is _not_ a bug in Xamarin.iOS. The correct intended way to address the run time error is indeed either to tell the linker to skip the entire `System.Reactive.Linq` assembly, or to manually preserve specific required parts of the assembly.


(To put it another way, it would be possible to file a feature request with the authors of System.Reactive.Linq to request that they audit the assembly for compatibility with the Xamarin.iOS linker.)


(To put it one more way, the "fix" for this bug was just to stop the _AOT_ error as in comment 0, thereby restoring the old "Attempting to JIT compile method" error as described in the "NOT a recent regression" section of comment 3.)

Hope that helps clear things up.



## Side note

For customers with Business and higher licenses who are following-up on RESOLVED or VERIFIED bugs, I'd recommend contacting the Support Team via email [1] rather than following-up directly in Bugzilla. That will help ensure the issue is addresses as quickly as possible as part of the normal Support Team work queue.

[1] https://kb.xamarin.com/customer/portal/articles/1632104-how-do-i-contact-xamarin-for-support-
Comment 12 Kent 2015-08-13 23:52:58 UTC
Ah, I see Brendan - sorry, I misunderstood.

That said, I would love to know how you go from the exception given to the determination of what needs to be excluded from linking. Is there any process documented on this because I actually have the exact same problem with another DLL that I have therefore included in its entirety.