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

XmlCompiledTransform.Load throws a System.PlatformNotSupportedException on iOS with .NET 8 #96920

Closed
bstadick opened this issue Jan 12, 2024 · 6 comments · Fixed by xamarin/xamarin-macios#19812

Comments

@bstadick
Copy link

Description

Calling XmlCompiledTransform.Load(XmlReader, XsltSettings, XmlResolver) in a .NET 8 iOS MAUI app throws a PlatformNotSupportedException. This call worked previously when targeting .NET 7 iOS MAUI. From the stacktrace it's likely that all XmlCompiledTransform.Load methods will throw this exception.

Reproduction Steps

  1. Create a .NET 8 iOS MAUI app.
  2. Initialize and call XmlCompiledTransform.Load(XmlReader, XsltSettings, XmlResolver) with a valid xsl file, xml resolver, and XsltSettings.EnableDocumentFunction = true and XsltSettings.EnableScript = false.
  3. Call to Load throws an exception.

Expected behavior

XmlCompiledTransform.Load loads the provided xsl transform.

Actual behavior

Calling XmlCompiledTransform.Load throws an exception with the given stack trace.

---> System.TypeInitializationException: The type initializer for 'System.Xml.Xsl.IlGen.XmlILModule' threw an exception.
---> System.PlatformNotSupportedException: Dynamic code generation is not supported on this platform.
at System.Reflection.Emit.AssemblyBuilder.ThrowDynamicCodeNotSupported()
at System.Reflection.Emit.AssemblyBuilder.EnsureDynamicCodeSupported()
at System.Reflection.Emit.RuntimeAssemblyBuilder..ctor(AssemblyName , AssemblyBuilderAccess )
at System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(AssemblyName , AssemblyBuilderAccess )
at System.Xml.Xsl.IlGen.XmlILModule.CreateLREModule()
at System.Xml.Xsl.IlGen.XmlILModule..cctor()
--- End of inner exception stack trace ---
at System.Xml.Xsl.XmlILGenerator.Generate(QilExpression , TypeBuilder )
at System.Xml.Xsl.XslCompiledTransform.CompileQilToMsil()
at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object , XsltSettings , XmlResolver , XmlResolver )
at System.Xml.Xsl.XslCompiledTransform.Load(XmlReader , XsltSettings , XmlResolver )

Regression?

XmlCompiledTransform.Load worked previously with Xamarin.iOS as well as .NET 7 iOS MAUI. It stopped working with .NET 8 iOS MAUI.

Known Workarounds

Using the obsolete XmlTransform class instead on iOS with .NET 8 works, but comes at the cost of XmlTransform.Transform having worse performance than XmlCompiledTransform.Transform.

Configuration

iOS

iOS 16.7.4
iPad Pro 12"

Xcode

Xcode 15.0
Build version 15A240d

Dotnet

.NET SDK:
Version: 8.0.101
Commit: 6eceda187b
Workload version: 8.0.100-manifests.8a1da915

Runtime Environment:
OS Name: Mac OS X
OS Version: 13.5
OS Platform: Darwin
RID: osx-arm64
Base Path: /usr/local/share/dotnet/sdk/8.0.101/

.NET workloads installed:
Workload version: 8.0.100-manifests.8a1da915
[maui-ios]
Installation Source: SDK 8.0.100
Manifest Version: 8.0.3/8.0.100
Manifest Path: /usr/local/share/dotnet/sdk-manifests/8.0.100/microsoft.net.sdk.maui/8.0.3/WorkloadManifest.json
Install Type: FileBased

Host:
Version: 8.0.1
Architecture: arm64
Commit: bf5e279

.NET SDKs installed:
6.0.418 [/usr/local/share/dotnet/sdk]
7.0.405 [/usr/local/share/dotnet/sdk]
8.0.101 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.26 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.15 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.26 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.15 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
x64 [/usr/local/share/dotnet/x64]
registered at [/etc/dotnet/install_location_x64]

Other information

These are the build properties set for the debug iOS app that may be relevant.

<SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchInterpreter>all</MtouchInterpreter>
<MtouchProfiling>False</MtouchProfiling>
<MtouchFastDev>False</MtouchFastDev>
<MtouchUseRefCounting>True</MtouchUseRefCounting>
<MtouchOptimizePNGs>True</MtouchOptimizePNGs>
<MtouchI18n>cjk,rare,west</MtouchI18n>
<MtouchUseSGen>True</MtouchUseSGen>
<MtouchEnableBitcode>False</MtouchEnableBitcode>
<MtouchFloat32>False</MtouchFloat32>
<EnableSGenConc>True</EnableSGenConc>
<MtouchDebug>True</MtouchDebug>
<MtouchEnableGenericValueTypeSharing>False</MtouchEnableGenericValueTypeSharing>
<MtouchUseLlvm>False</MtouchUseLlvm>
<MtouchUseThumb>False</MtouchUseThumb>
<MtouchNoSymbolStrip>True</MtouchNoSymbolStrip>
<RuntimeIdentifiers>ios-arm64</RuntimeIdentifiers>
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jan 12, 2024
@ghost
Copy link

ghost commented Jan 12, 2024

Tagging subscribers to this area: @dotnet/area-system-xml
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Calling XmlCompiledTransform.Load(XmlReader, XsltSettings, XmlResolver) in a .NET 8 iOS MAUI app throws a PlatformNotSupportedException. This call worked previously when targeting .NET 7 iOS MAUI. From the stacktrace it's likely that all XmlCompiledTransform.Load methods will throw this exception.

Reproduction Steps

  1. Create a .NET 8 iOS MAUI app.
  2. Initialize and call XmlCompiledTransform.Load(XmlReader, XsltSettings, XmlResolver) with a valid xsl file, xml resolver, and XsltSettings.EnableDocumentFunction = true and XsltSettings.EnableScript = false.
  3. Call to Load throws an exception.

Expected behavior

XmlCompiledTransform.Load loads the provided xsl transform.

Actual behavior

Calling XmlCompiledTransform.Load throws an exception with the given stack trace.

---> System.TypeInitializationException: The type initializer for 'System.Xml.Xsl.IlGen.XmlILModule' threw an exception.
---> System.PlatformNotSupportedException: Dynamic code generation is not supported on this platform.
at System.Reflection.Emit.AssemblyBuilder.ThrowDynamicCodeNotSupported()
at System.Reflection.Emit.AssemblyBuilder.EnsureDynamicCodeSupported()
at System.Reflection.Emit.RuntimeAssemblyBuilder..ctor(AssemblyName , AssemblyBuilderAccess )
at System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(AssemblyName , AssemblyBuilderAccess )
at System.Xml.Xsl.IlGen.XmlILModule.CreateLREModule()
at System.Xml.Xsl.IlGen.XmlILModule..cctor()
--- End of inner exception stack trace ---
at System.Xml.Xsl.XmlILGenerator.Generate(QilExpression , TypeBuilder )
at System.Xml.Xsl.XslCompiledTransform.CompileQilToMsil()
at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object , XsltSettings , XmlResolver , XmlResolver )
at System.Xml.Xsl.XslCompiledTransform.Load(XmlReader , XsltSettings , XmlResolver )

Regression?

XmlCompiledTransform.Load worked previously with Xamarin.iOS as well as .NET 7 iOS MAUI. It stopped working with .NET 8 iOS MAUI.

Known Workarounds

Using the obsolete XmlTransform class instead on iOS with .NET 8 works, but comes at the cost of XmlTransform.Transform having worse performance than XmlCompiledTransform.Transform.

Configuration

iOS

iOS 16.7.4
iPad Pro 12"

Xcode

Xcode 15.0
Build version 15A240d

Dotnet

.NET SDK:
Version: 8.0.101
Commit: 6eceda187b
Workload version: 8.0.100-manifests.8a1da915

Runtime Environment:
OS Name: Mac OS X
OS Version: 13.5
OS Platform: Darwin
RID: osx-arm64
Base Path: /usr/local/share/dotnet/sdk/8.0.101/

.NET workloads installed:
Workload version: 8.0.100-manifests.8a1da915
[maui-ios]
Installation Source: SDK 8.0.100
Manifest Version: 8.0.3/8.0.100
Manifest Path: /usr/local/share/dotnet/sdk-manifests/8.0.100/microsoft.net.sdk.maui/8.0.3/WorkloadManifest.json
Install Type: FileBased

Host:
Version: 8.0.1
Architecture: arm64
Commit: bf5e279

.NET SDKs installed:
6.0.418 [/usr/local/share/dotnet/sdk]
7.0.405 [/usr/local/share/dotnet/sdk]
8.0.101 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.26 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.15 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.26 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.15 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
x64 [/usr/local/share/dotnet/x64]
registered at [/etc/dotnet/install_location_x64]

Other information

These are the build properties set for the debug iOS app that may be relevant.

<SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchInterpreter>all</MtouchInterpreter>
<MtouchProfiling>False</MtouchProfiling>
<MtouchFastDev>False</MtouchFastDev>
<MtouchUseRefCounting>True</MtouchUseRefCounting>
<MtouchOptimizePNGs>True</MtouchOptimizePNGs>
<MtouchI18n>cjk,rare,west</MtouchI18n>
<MtouchUseSGen>True</MtouchUseSGen>
<MtouchEnableBitcode>False</MtouchEnableBitcode>
<MtouchFloat32>False</MtouchFloat32>
<EnableSGenConc>True</EnableSGenConc>
<MtouchDebug>True</MtouchDebug>
<MtouchEnableGenericValueTypeSharing>False</MtouchEnableGenericValueTypeSharing>
<MtouchUseLlvm>False</MtouchUseLlvm>
<MtouchUseThumb>False</MtouchUseThumb>
<MtouchNoSymbolStrip>True</MtouchNoSymbolStrip>
<RuntimeIdentifiers>ios-arm64</RuntimeIdentifiers>
Author: bstadick
Assignees: -
Labels:

area-System.Xml, untriaged

Milestone: -

@vcsjones vcsjones added the os-ios Apple iOS label Jan 13, 2024
@ghost
Copy link

ghost commented Jan 13, 2024

Tagging subscribers to 'os-ios': @steveisok, @akoeplinger, @kotlarmilos
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Calling XmlCompiledTransform.Load(XmlReader, XsltSettings, XmlResolver) in a .NET 8 iOS MAUI app throws a PlatformNotSupportedException. This call worked previously when targeting .NET 7 iOS MAUI. From the stacktrace it's likely that all XmlCompiledTransform.Load methods will throw this exception.

Reproduction Steps

  1. Create a .NET 8 iOS MAUI app.
  2. Initialize and call XmlCompiledTransform.Load(XmlReader, XsltSettings, XmlResolver) with a valid xsl file, xml resolver, and XsltSettings.EnableDocumentFunction = true and XsltSettings.EnableScript = false.
  3. Call to Load throws an exception.

Expected behavior

XmlCompiledTransform.Load loads the provided xsl transform.

Actual behavior

Calling XmlCompiledTransform.Load throws an exception with the given stack trace.

---> System.TypeInitializationException: The type initializer for 'System.Xml.Xsl.IlGen.XmlILModule' threw an exception.
---> System.PlatformNotSupportedException: Dynamic code generation is not supported on this platform.
at System.Reflection.Emit.AssemblyBuilder.ThrowDynamicCodeNotSupported()
at System.Reflection.Emit.AssemblyBuilder.EnsureDynamicCodeSupported()
at System.Reflection.Emit.RuntimeAssemblyBuilder..ctor(AssemblyName , AssemblyBuilderAccess )
at System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(AssemblyName , AssemblyBuilderAccess )
at System.Xml.Xsl.IlGen.XmlILModule.CreateLREModule()
at System.Xml.Xsl.IlGen.XmlILModule..cctor()
--- End of inner exception stack trace ---
at System.Xml.Xsl.XmlILGenerator.Generate(QilExpression , TypeBuilder )
at System.Xml.Xsl.XslCompiledTransform.CompileQilToMsil()
at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object , XsltSettings , XmlResolver , XmlResolver )
at System.Xml.Xsl.XslCompiledTransform.Load(XmlReader , XsltSettings , XmlResolver )

Regression?

XmlCompiledTransform.Load worked previously with Xamarin.iOS as well as .NET 7 iOS MAUI. It stopped working with .NET 8 iOS MAUI.

Known Workarounds

Using the obsolete XmlTransform class instead on iOS with .NET 8 works, but comes at the cost of XmlTransform.Transform having worse performance than XmlCompiledTransform.Transform.

Configuration

iOS

iOS 16.7.4
iPad Pro 12"

Xcode

Xcode 15.0
Build version 15A240d

Dotnet

.NET SDK:
Version: 8.0.101
Commit: 6eceda187b
Workload version: 8.0.100-manifests.8a1da915

Runtime Environment:
OS Name: Mac OS X
OS Version: 13.5
OS Platform: Darwin
RID: osx-arm64
Base Path: /usr/local/share/dotnet/sdk/8.0.101/

.NET workloads installed:
Workload version: 8.0.100-manifests.8a1da915
[maui-ios]
Installation Source: SDK 8.0.100
Manifest Version: 8.0.3/8.0.100
Manifest Path: /usr/local/share/dotnet/sdk-manifests/8.0.100/microsoft.net.sdk.maui/8.0.3/WorkloadManifest.json
Install Type: FileBased

Host:
Version: 8.0.1
Architecture: arm64
Commit: bf5e279

.NET SDKs installed:
6.0.418 [/usr/local/share/dotnet/sdk]
7.0.405 [/usr/local/share/dotnet/sdk]
8.0.101 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.26 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.15 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.26 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.15 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
x64 [/usr/local/share/dotnet/x64]
registered at [/etc/dotnet/install_location_x64]

Other information

These are the build properties set for the debug iOS app that may be relevant.

<SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchInterpreter>all</MtouchInterpreter>
<MtouchProfiling>False</MtouchProfiling>
<MtouchFastDev>False</MtouchFastDev>
<MtouchUseRefCounting>True</MtouchUseRefCounting>
<MtouchOptimizePNGs>True</MtouchOptimizePNGs>
<MtouchI18n>cjk,rare,west</MtouchI18n>
<MtouchUseSGen>True</MtouchUseSGen>
<MtouchEnableBitcode>False</MtouchEnableBitcode>
<MtouchFloat32>False</MtouchFloat32>
<EnableSGenConc>True</EnableSGenConc>
<MtouchDebug>True</MtouchDebug>
<MtouchEnableGenericValueTypeSharing>False</MtouchEnableGenericValueTypeSharing>
<MtouchUseLlvm>False</MtouchUseLlvm>
<MtouchUseThumb>False</MtouchUseThumb>
<MtouchNoSymbolStrip>True</MtouchNoSymbolStrip>
<RuntimeIdentifiers>ios-arm64</RuntimeIdentifiers>
Author: bstadick
Assignees: -
Labels:

area-System.Xml, untriaged, os-ios

Milestone: -

@akoeplinger
Copy link
Member

akoeplinger commented Jan 15, 2024

Can you please try UseInterpreter=true instead of MtouchInterpreter?

Note that XslCompiledTransform requires dynamic code generation so it is fundamentally incompatible with the full AOT environment required by iOS. Enabling the interpreter works around that by interpreting all code but looks like MtouchInterpreter didn't cause it to get enabled correctly anymore.

@bstadick
Copy link
Author

Can you please try UseInterpreter=true instead of MtouchInterpreter?

Note that XslCompiledTransform requires dynamic code generation so it is fundamentally incompatible with the full AOT environment required by iOS. Enabling the interpreter works around that by interpreting all code but looks like MtouchInterpreter didn't cause it to get enabled correctly anymore.

Thanks @akoeplinger for the suggestion. Setting <UseInterpreter>true</UseInterpreter> did allow for me to use the XmlCompiledTransform.Load with .NET 8 on iOS without throwing an exception. I also kept the <MtouchInterpreter>all</MtouchInterpreter> in place.

Previously setting UseInterpreter = true was a synonym for MtouchInterpreter = all with iOS. I don't know if there was some sort of undocumented change or I missed something that this behavior changed with the .NET 8 SDK. So this may be instead a regression or undocumented change in the build settings instead of the XmlCompiledTransform class.

@akoeplinger
Copy link
Member

@rolfbjarne are you aware of any MtouchInterpreter=all/UseInterpreter=true inconsistencies?

@rolfbjarne
Copy link
Member

@rolfbjarne are you aware of any MtouchInterpreter=all/UseInterpreter=true inconsistencies?

Yes, we have a bug in this area, which should be fixed with xamarin/xamarin-macios#19812.

rolfbjarne added a commit to xamarin/xamarin-macios that referenced this issue Jan 22, 2024
The canonical property we use for the interpreter is `MtouchInterpreter` - and
the interpreter is enabled if `MtouchInterpreter` is set to any value (the
`MtouchInterpreter` value is used to select which assemblies to interpret, the
only way to completely disable the interpreter is to not set
`MtouchInterpreter` at all).

So fix a couple of cases of wrong comparison:

* Don't use `UseInterpreter` - which is used to compute a specific value for
  `MtouchInterpreter` - because developers don't have to set `UseInterpreter`
  to enable the interpreter, they can set `MtouchInterpreter` directly.
* Don't compare `MtouchInterpreter` with `true`: that only checks if the
  assembly "true" is interpreted (which it rarely is).

Fixes dotnet/runtime#96920.
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jan 22, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Feb 22, 2024
rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this issue Jun 17, 2024
The canonical property we use for the interpreter is `MtouchInterpreter` - and
the interpreter is enabled if `MtouchInterpreter` is set to any value (the
`MtouchInterpreter` value is used to select which assemblies to interpret, the
only way to completely disable the interpreter is to not set
`MtouchInterpreter` at all).

So fix a couple of cases of wrong comparison:

* Don't use `UseInterpreter` - which is used to compute a specific value for
  `MtouchInterpreter` - because developers don't have to set `UseInterpreter`
  to enable the interpreter, they can set `MtouchInterpreter` directly.
* Don't compare `MtouchInterpreter` with `true`: that only checks if the
  assembly "true" is interpreted (which it rarely is).

Fixes dotnet/runtime#96920.
rolfbjarne added a commit to xamarin/xamarin-macios that referenced this issue Jun 18, 2024
… is enabled. (#20732)

The canonical property we use for the interpreter is `MtouchInterpreter` - and
the interpreter is enabled if `MtouchInterpreter` is set to any value (the
`MtouchInterpreter` value is used to select which assemblies to interpret, the
only way to completely disable the interpreter is to not set
`MtouchInterpreter` at all).

So fix a couple of cases of wrong comparison:

* Don't use `UseInterpreter` - which is used to compute a specific value for
  `MtouchInterpreter` - because developers don't have to set `UseInterpreter`
  to enable the interpreter, they can set `MtouchInterpreter` directly.
* Don't compare `MtouchInterpreter` with `true`: that only checks if the
  assembly "true" is interpreted (which it rarely is).

Fixes dotnet/runtime#96920.

This is a backport of #19812 and #20696.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants