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

[BUG] LiteDB 5.0.X crashes in iOS due to Emitting dynamic code #2082

Open
ryancheung opened this issue Oct 13, 2021 · 17 comments
Open

[BUG] LiteDB 5.0.X crashes in iOS due to Emitting dynamic code #2082

ryancheung opened this issue Oct 13, 2021 · 17 comments
Labels

Comments

@ryancheung
Copy link

Version

LiteDB 5.X/iOS/.NET 6.0

Describe the bug

The LiteDB 5.0.X crashes in .NET 6.0 ios but LiteDB 4.0.X works fine.
The linq expressions used in 5.0.X seems not AOT friendly any more. The expression compiling of some of them trigger usage of System.Reflection.Emit.

Code to Reproduce

https://github.com/ryancheung/LiteDB-iOS-Crash-Repro

Expected behavior

It should not crash with emitting dynamic code while System.Linq.Expressions.Expression.Compile().

Screenshots/Stacktrace

Attempting to JIT compile method '(wrapper dynamic-method) LiteDB.BsonValue object:Thunk1ret_BsonValue_IEnumerable`1_BsonDocument_BsonValue_Collation_BsonDocument (System.Func`2<object[], object>,System.Collections.Generic.IEnumerable`1<LiteDB.BsonDocument>,LiteDB.BsonDocument,LiteDB.BsonValue,LiteDB.Collation,LiteDB.BsonDocument)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.
 (System.ExecutionEngineException)
   at System.Delegate.CreateDelegate(Type , Object , MethodInfo , Boolean , Boolean )
   at System.Delegate.CreateDelegate(Type , Object , MethodInfo , Boolean )
   at System.Delegate.CreateDelegate(Type , Object , MethodInfo )
   at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type , Object )
   at System.Dynamic.Utils.DelegateHelpers.CreateObjectArrayDelegateRefEmit(Type , Func`2 )
   at System.Dynamic.Utils.DelegateHelpers.CreateObjectArrayDelegate(Type , Func`2 )
   at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate(Type )
   at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate(IStrongBox[] )
   at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate()
   at System.Linq.Expressions.Expression`1[[LiteDB.BsonExpressionScalarDelegate, LiteDB, Version=5.0.11.0, Culture=neutral, PublicKeyToken=4ee40123013c9f27]].Compile()
   at LiteDB.BsonExpression.<>c__DisplayClass70_0.<Compile>b__0(String s)
   at System.Collections.Concurrent.ConcurrentDictionary`2[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[LiteDB.BsonExpressionScalarDelegate, LiteDB, Version=5.0.11.0, Culture=neutral, PublicKeyToken=4ee40123013c9f27]].GetOrAdd(String , Func`2 )
   at LiteDB.BsonExpression.Compile(BsonExpression expr, ExpressionContext context)
   at LiteDB.BsonExpression.ParseAndCompile(Tokenizer tokenizer, BsonExpressionParserMode mode, BsonDocument parameters, DocumentScope scope)
   at LiteDB.BsonExpression.Create(Tokenizer tokenizer, BsonExpressionParserMode mode, BsonDocument parameters)
   at LiteDB.BsonExpression.Create(String expression, BsonDocument parameters)
   at LiteDB.BsonExpression.Create(String expression)
   at LiteDB.BsonExpression..cctor()
@ryancheung ryancheung added the bug label Oct 13, 2021
@gvs55
Copy link

gvs55 commented Jul 29, 2022

+1

Spent hours today trying to figure out why only iOS was crashing in my Maui blazor hybrid app, and finally figured out how to get the actual error and stack trace. It was this same issue. Too bad it's still broken almost a year later.

@7702244
Copy link

7702244 commented Dec 4, 2022

Does anybody found a solution?

@DDHSchmidt
Copy link

Not quite a solution but a workaround. You can try to use interpreter-mode instead of LLVM. Comes with a performance hit but is so far the only workaronud I found.
Add the following to your iOS-Release target in your csproj-file:
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-ios|AnyCPU'"> <UseInterpreter>true</UseInterpreter> </PropertyGroup>

@shmoe01
Copy link

shmoe01 commented May 2, 2023

We are also experiencing the same issue. Hope to see a fix soon

@lylerolleman
Copy link

Just ran into this as well

Seems like an awfully important bug to be just... completely ignoring? LiteDB was always my go to for cross platform work, and missing iOS makes it pretty useless if I want to use something remotely recent.

@DDHSchmidt
Copy link

@lylerolleman Actually there has been some progress on Microsoft's side as well. As far as I understood there are supposed to be mitigations in .Net 8 preview 7 so that this exception shouldn't occur anymore.
Unfortunately Preview 7 has other, intolerable errors for my project so I'm unable to test this until the next Preview of .Net 8 is released :/

@olekssokol
Copy link

olekssokol commented Sep 23, 2023

Not quite a solution but a workaround. You can try to use interpreter-mode instead of LLVM. Comes with a performance hit but is so far the only workaronud I found. Add the following to your iOS-Release target in your csproj-file: <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-ios|AnyCPU'"> <UseInterpreter>true</UseInterpreter> </PropertyGroup>

It worked for me

@XhaiiCo
Copy link

XhaiiCo commented Oct 25, 2023

Not quite a solution but a workaround. You can try to use interpreter-mode instead of LLVM. Comes with a performance hit but is so far the only workaronud I found. Add the following to your iOS-Release target in your csproj-file: <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-ios|AnyCPU'"> <UseInterpreter>true</UseInterpreter> </PropertyGroup>

It worked, thx

@MartinZikmund
Copy link

MartinZikmund commented Jun 28, 2024

The underlying issue seems to have been fixed in .NET 8 dotnet/runtime#87924 and as per my test it seems the repro above no longer crashes if targeting .NET 8! (even on device)

@Digifais
Copy link

Digifais commented Aug 28, 2024

This is still an issue for me in .NET 8 for iOS.

@MartinZikmund
Copy link

@Digifais Do you have a repro for it? I have used the latest stable LiteDB on iOS with .NET 8 without issues so far

@Digifais
Copy link

Digifais commented Aug 29, 2024

@MartinZikmund Using LiteRepository and calling _recentSearchesRepository.Fetch<RecentSearch>(x => true) for example.

Another example is: return _recentSearchesDatabase.DatabaseInstance.GetCollection<RecentSearch>().FindAll().ToList() where DatabaseInstance is of type LiteDatabase.

@Digifais
Copy link

Digifais commented Aug 29, 2024

@MartinZikmund If you have any suggestions on how to fix/prevent this, that would be great. For now, I'm working around it by using the Mono interpreter for the LiteDB assembly only as such: <MtouchInterpreter>-all,LiteDB</MtouchInterpreter>.

Also, I'm not quite sure if this has been fixed, look at dotnet/runtime#94063

@DDHSchmidt
Copy link

@Digifais
I forgot to update this issue after my last comment, but we have no more issues with LiteDB in Release mode on iOS (.Net 8).
Maybe post more lines from your build configuration in your csproj ?

Ours is currently looking like this:

<PropertyGroup Condition="$(Configuration.Contains('Release')) And $(TargetFramework.Contains('ios'))">
      <!-- ApplicationId, Entitlements, CodesignKey, etc. omitted -->
      <MtouchInterpreter>-all,System.Private.Xml,System.Collections.Immutable</MtouchInterpreter>
      <!-- System.Private.Xml is for our XSLT transformations that depend on reflection operations happening in that assembly -->
      <!-- System.Collections.Immutable was chosen for an exception in CommunityToolKit's "toast" component: https://github.com/CommunityToolkit/Maui/Issues/1752 -->
      <MtouchFloat32>true</MtouchFloat32>
	<MtouchLink>SdkOnly</MtouchLink>
    </PropertyGroup>

We don't experience any more crashes linked to LiteDB in our Maui app on .Net 8.
If everything fails for you, then maybe the "sledgehammer" aka <UseInterpreter>true</UseInterpreter> might still be an option for you. Have you tried that already?

@Digifais
Copy link

Digifais commented Aug 29, 2024

@DDHSchmidt As stated in my last comment, I'm indeed currently working around it by using <MtouchInterpreter>-all,LiteDB</MtouchInterpreter>

As for my csproj, it's actually pretty basic, mind you, I'm not using MAUI but a native .NET for iOS app:

<PropertyGroup>
    <TargetFramework>net8.0-ios</TargetFramework>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>true</ImplicitUsings>
    <ApplicationTitle>xxx</ApplicationTitle>
    <ApplicationId>xxx</ApplicationId>
    <ApplicationVersion>1</ApplicationVersion>
    <ApplicationDisplayVersion>1.5.0</ApplicationDisplayVersion>
    <SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>
    <EnableSGenConc>true</EnableSGenConc>
    <FirebaseCrashlyticsUploadSymbolsEnabled>True</FirebaseCrashlyticsUploadSymbolsEnabled>
    <MtouchInterpreter>-all,LiteDB</MtouchInterpreter>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <CreatePackage>false</CreatePackage>
    <CodesignEntitlements>Entitlements\Development\Entitlements.plist</CodesignEntitlements>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <CreatePackage>false</CreatePackage>
    <CodesignEntitlements>Entitlements\Preview\Entitlements.plist</CodesignEntitlements>
    <MtouchLink>Full</MtouchLink>
  </PropertyGroup>

@DDHSchmidt
Copy link

@Digifais
Can you change that <MtouchLink>Full</MtouchLink> to <MtouchLink>SdkOnly</MtouchLink> and see if it helps?

Full linking is can full of worms and only as recent as .Net 9 Preview have Microsoft themselves acknowledged that it might be safe to use now ;)

@Digifais
Copy link

@DDHSchmidt Tried that before, makes no difference, even setting it to None.

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

No branches or pull requests

10 participants