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

[mono][ios] MonoAOT crashes when the app uses SQLite library with a DateTime member in DTO #98428

Open
ivanpovazan opened this issue Feb 14, 2024 · 3 comments

Comments

@ivanpovazan
Copy link
Member

Description

When an iOS app uses SQLite library with a DTO that has a DateTime member and tries to iterate over the collection of such objects, it crashes with:

*** Terminating app due to uncaught exception 'System.ExecutionEngineException', reason: 'Attempting to JIT compile method '(wrapper delegate-invoke) void System.Action`2<SQLiteDemo.CacheDto, System.DateTime>:invoke_callvirt_void_T1_T2 (SQLiteDemo.CacheDto,System.DateTime)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
 (System.ExecutionEngineException)
   at SQLite.FastColumnSetter.<>c__DisplayClass2_0`2[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.DateTime, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<CreateTypedSetterDelegate>b__0(CacheDto o, sqlite3_stmt stmt, Int32 i)
   at SQLite.SQLiteCommand.<ExecuteDeferredQuery>d__12`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at System.Collections.Generic.List`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutr<…>

The original reported issue dates back to mono/mono#21270 where Mono was crashing with slightly different error message:

Unhandled managed exception: Attempting to JIT compile method '(wrapper delegate-invoke) void :invoke_callvirt_void_CacheDto_DateTime(App21.CacheDto, System.DateTime)' while running in aot-only mode.

and was reported also in: dotnet/maui#20342

This is still reproducible with net8.0 release.

Repro

This can be verified with a template net8.0-ios app :

  • creating a project and adding SQLite references
dotnet new ios -n "SQLiteDemo" ; cd SQLiteDemo
dotnet add package SQLitePCLRaw.bundle_green --version 2.1.0
dotnet add package sqlite-net-pcl --version 1.8.0-beta
  • adding a sample code in a Demo.cs:
namespace SQLiteDemo;

using SQLite;
using System.Linq;

public interface ICacheDto
{
	string Type { get; set; }

	DateTime Date { get; set; }

	string Id { get; set; }
}

public sealed class CacheDto : ICacheDto
{
	public string Type { get; set; }

	public DateTime Date { get; set; }

	public string Id { get; set; }
}

public class Demo
{
	public static void Crash()
	{
		var databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData.db");
		if (File.Exists(databasePath))
		{
			File.Delete(databasePath);
		}

		var db = new SQLiteConnection(databasePath);
		db.CreateTable<CacheDto>();
		AddCache(db, "test");

		var stocks = db.Table<CacheDto>().Cast<ICacheDto>();

		foreach (var stock in stocks)
		{
			Console.WriteLine("Where StartsWith: t " + stock?.Type);
		}
	}

	public static void AddCache(SQLiteConnection db, string type) {
		var stock = new CacheDto() {
			Type = type,
			Id = Guid.NewGuid().ToString(),
		};

		db.Insert(stock);
	}
}
  • Invoke the code from AppDelegate.cs
...
		Window.MakeKeyAndVisible ();
		
		Demo.Crash();
  • The app crashes with:
*** Terminating app due to uncaught exception 'System.ExecutionEngineException', reason: 'Attempting to JIT compile method '(wrapper delegate-invoke) void System.Action`2<SQLiteDemo.CacheDto, System.DateTime>:invoke_callvirt_void_T1_T2 (SQLiteDemo.CacheDto,System.DateTime)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
 (System.ExecutionEngineException)
   at SQLite.FastColumnSetter.<>c__DisplayClass2_0`2[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.DateTime, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<CreateTypedSetterDelegate>b__0(CacheDto o, sqlite3_stmt stmt, Int32 i)
   at SQLite.SQLiteCommand.<ExecuteDeferredQuery>d__12`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at System.Collections.Generic.List`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutr<…>

Workarounds

  • Known workaround is enabling the interpreter via
<UseInterpreter>true</UseInterpreter>

Additional notes

I assume we are again hitting the problem of heavy use of generics and arbitrary delegates which are not AOT friendly.

/cc: @vargaz

@ghost
Copy link

ghost commented Feb 14, 2024

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

Issue Details

Description

When an iOS app uses SQLite library with a DTO that has a DateTime member and tries to iterate over the collection of such objects, it crashes with:

*** Terminating app due to uncaught exception 'System.ExecutionEngineException', reason: 'Attempting to JIT compile method '(wrapper delegate-invoke) void System.Action`2<SQLiteDemo.CacheDto, System.DateTime>:invoke_callvirt_void_T1_T2 (SQLiteDemo.CacheDto,System.DateTime)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
 (System.ExecutionEngineException)
   at SQLite.FastColumnSetter.<>c__DisplayClass2_0`2[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.DateTime, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<CreateTypedSetterDelegate>b__0(CacheDto o, sqlite3_stmt stmt, Int32 i)
   at SQLite.SQLiteCommand.<ExecuteDeferredQuery>d__12`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at System.Collections.Generic.List`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutr<…>

The original reported issue dates back to mono/mono#21270 where Mono was crashing with slightly different error message:

Unhandled managed exception: Attempting to JIT compile method '(wrapper delegate-invoke) void :invoke_callvirt_void_CacheDto_DateTime(App21.CacheDto, System.DateTime)' while running in aot-only mode.

and was reported also in: dotnet/maui#20342

This is still reproducible with net8.0 release.

Repro

This can be verified with a template net8.0-ios app :

  • creating a project and adding SQLite references
dotnet new ios -n "SQLiteDemo" ; cd SQLiteDemo
dotnet add package SQLitePCLRaw.bundle_green --version 2.1.0
dotnet add package sqlite-net-pcl --version 1.8.0-beta
  • adding a sample code in a Demo.cs:
namespace SQLiteDemo;

using SQLite;
using System.Linq;

public interface ICacheDto
{
	string Type { get; set; }

	DateTime Date { get; set; }

	string Id { get; set; }
}

public sealed class CacheDto : ICacheDto
{
	public string Type { get; set; }

	public DateTime Date { get; set; }

	public string Id { get; set; }
}

public class Demo
{
	public static void Crash()
	{
		var databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData.db");
		if (File.Exists(databasePath))
		{
			File.Delete(databasePath);
		}

		var db = new SQLiteConnection(databasePath);
		db.CreateTable<CacheDto>();
		AddCache(db, "test");

		var stocks = db.Table<CacheDto>().Cast<ICacheDto>();

		foreach (var stock in stocks)
		{
			Console.WriteLine("Where StartsWith: t " + stock?.Type);
		}
	}

	public static void AddCache(SQLiteConnection db, string type) {
		var stock = new CacheDto() {
			Type = type,
			Id = Guid.NewGuid().ToString(),
		};

		db.Insert(stock);
	}
}
  • Invoke the code from AppDelegate.cs
...
		Window.MakeKeyAndVisible ();
		
		Demo.Crash();
  • The app crashes with:
*** Terminating app due to uncaught exception 'System.ExecutionEngineException', reason: 'Attempting to JIT compile method '(wrapper delegate-invoke) void System.Action`2<SQLiteDemo.CacheDto, System.DateTime>:invoke_callvirt_void_T1_T2 (SQLiteDemo.CacheDto,System.DateTime)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
 (System.ExecutionEngineException)
   at SQLite.FastColumnSetter.<>c__DisplayClass2_0`2[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.DateTime, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<CreateTypedSetterDelegate>b__0(CacheDto o, sqlite3_stmt stmt, Int32 i)
   at SQLite.SQLiteCommand.<ExecuteDeferredQuery>d__12`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at System.Collections.Generic.List`1[[SQLiteDemo.CacheDto, SQLiteDemo, Version=1.0.0.0, Culture=neutr<…>

Workarounds

  • Known workaround is enabling the interpreter via
<UseInterpreter>true</UseInterpreter>

Additional notes

I assume we are again hitting the problem of heavy use of generics and arbitrary delegates which are not AOT friendly.

/cc: @vargaz

Author: ivanpovazan
Assignees: -
Labels:

area-Codegen-AOT-mono, os-ios

Milestone: Future

@vargaz
Copy link
Contributor

vargaz commented Feb 15, 2024

This is not supposed to happen, because we generate gsharedvt version for these wrappers which can handle any type in theory.

@JeroenBer
Copy link

Probably also related: praeclarum/sqlite-net#1067

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants