Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin Crash on iOS only on SQLite update call for model

Tags:

sqlite

xamarin

Application crashes doing an update using SQLite PCL on only iOS. Works fine on Android. Anyone have any ideas?

My SQLite NuGet

enter image description here

Crashes at App.SqliteConnection.Update(pAssetRecovery)

public static async Task Update(Models.Model_AssetRecovery pAssetRecovery)
    {
        try
        {
            await Task.Run(() => App.SqliteConnection.Update(pAssetRecovery));
        }
        catch (SystemException ex)
        {}

    }

The Model Being Saved

    [Table("tblAssetRecovery")]
    public class Model_AssetRecovery : _Model_Base
    {
        [PrimaryKey, NotNull, Unique]
        public string strAssetRecoveryID { get; set; }
        public string strAssignmentID { get; set; }
        public string strAssetID { get; set; }
        public int intAssignmentIdentity { get; set; }
        public int intCurrentPage { get; set; }
        public int intRecoveryUsersID { get; set; }
        public string strDebtorAddressID { get; set; }
        public string strRecoveryAddress1 { get; set; }
        public string strRecoveryAddress2 { get; set; }
        public string strRecoveryCity { get; set; }
        public string strRecoveryZipcode { get; set; }
        public string strRecoveryLongitude { get; set; }
        public string strRecoveryLatitude { get; set; }
        public int intRecoveryStateID { get; set; }
        public int intRecoveryCountryID { get; set; }
        public string strRecoveryDate { get; set; }
        public TimeSpan tspanRecoveryTime { get; set; }
        public string strRecoveryNotificationAgency { get; set; }
        public string strRecoveryNotificationPhone { get; set; }
        public string strRecoveryNotificationDate { get; set; }
        public TimeSpan tspanRecoveryNotificationTime { get; set; }
        public string strRecoveryNotificationNote { get; set; }
        public string strRecoveryNotificaitonAddress1 { get; set; }
        public string strRecoveryNotificaitonAddress2 { get; set; }
        public string strRecoveryNotificaitonCity { get; set; }
        public string strRecoveryNotificaitonZipCode { get; set; }
        public string strDMVInfo { get; set; }
        public string strRecoveryNotificaitonCounty { get; set; }
        public int intRecoveryNotificationStateID { get; set; }
        public string strAssetRecoveryParagraph { get; set; }
        public int intTowDollyUsed { get; set; }
        public int intIsLPRRecovery { get; set; }
        public string strAssetColor { get; set; }
        public int intAssetYear { get; set; }
        public string strAssetMake { get; set; }
        public string strAssetModel { get; set; }
        public string strAssetVIN { get; set; }
        public string strAssetBodyStyle { get; set; }
        public int intRecoveryAddressSource { get; set; }
        public int intRecoveryAddressType { get; set; }
        public string strCounty { get; set; }
        public int intStorageLotID { get; set; }
        public int intKeysObtained { get; set; }
        public int intKeysPlanToObtain { get; set; }
        public int intKeysObtainedSource { get; set; }
        public int intOdometerReading { get; set; }
        public int intOdometerType { get; set; }
        public string strCompletionMessage { get; set; }
        public int intAccessToInterior { get; set; }
        public int intIsAssetDamaged { get; set; }
        public int intAirbagsDeployed { get; set; }
        public int? intVehicleLicenseStateID { get; set; }
        public string strPlateNumber { get; set; }
        public int intAssignmentType { get; set; }
        public int intAssignmentStatus { get; set; }
        public int intLPRProvider { get; set; }
        public int intCanYouRecordMileage { get; set; }


    }
}

iOS DI SQLiteHandler

class SQLite_iOS : ISQLiteConnection
    {
        public SQLiteConnection GetConnection()
        {
            try
            {
                var sqliteFilename = "MyApp.db3";
                string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
                string libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder
                var path = Path.Combine(libraryPath, sqliteFilename);
                // Create the connection
                var plat = new SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS();
                var conn = new SQLite.Net.SQLiteConnection(plat, path);
                // Return the database connection
                return conn;
            }
            catch (SystemException ex)
            {
                namespace.Classes.Helpers.Helper_ErrorHandling.SendErrorToServer(ex, "GetConnection_iOS", "GetConnection_iOS");
                //Device.BeginInvokeOnMainThread(() => App.iAppNavigation.GetErrorPage());
                return null;
            }
        }
    }

Visual Studio Error

2015-05-15 16:47:19.775 namespace[4678:182349] critical: Stacktrace:

2015-05-15 16:47:19.789 namespace[4678:182349] critical:   at <unknown> <0xffffffff>
2015-05-15 16:47:19.789 namespace[4678:182349] critical:   at (wrapper managed-to-native) SQLite.Net.Platform.XamarinIOS.SQLiteApiIOSInternal.sqlite3_prepare_v2 (intptr,string,int,intptr&,intptr) <IL 0x00028, 0xffffffff>
2015-05-15 16:47:19.789 namespace[4678:182349] critical:   at SQLite.Net.Platform.XamarinIOS.SQLiteApiIOS.Prepare2 (SQLite.Net.Interop.IDbHandle,string) <IL 0x0001c, 0x00190>
2015-05-15 16:47:19.790 namespace[4678:182349] critical:   at SQLite.Net.SQLiteCommand.Prepare () <IL 0x0001c, 0x000e5>
2015-05-15 16:47:19.790 namespace[4678:182349] critical:   at SQLite.Net.SQLiteCommand.ExecuteNonQuery () <IL 0x00017, 0x000db>
2015-05-15 16:47:19.790 namespace[4678:182349] critical:   at SQLite.Net.SQLiteConnection.Execute (string,object[]) <IL 
0x00044, 0x00214>
2015-05-15 16:47:19.790 namespace[4678:182349] critical:   at SQLite.Net.SQLiteConnection.Update (object,System.Type) <IL 0x00104, 0x00b58>
2015-05-15 16:47:19.791 namespace[4678:182349] critical:   at SQLite.Net.SQLiteConnection.Update (object) <IL 0x0000d, 0x000e2>
2015-05-15 16:47:19.791 namespace[4678:182349] critical:   at namespace.Classes.Helpers.SQLite.Helper_SQLite_AssetRecovery/<>c__DisplayClass9.<Update>b__7 () [0x00000] in d:\LocalRepository\namespace\namespace\namespace\Classes\Helpers\SQLite\Helper_SQLite_AssetRecovery.cs:32
2015-05-15 16:47:19.791 namespace[4678:182349] critical:   at System.Threading.Tasks.Task`1<int>.InnerInvoke () [0x00012] in /Users/builder/data/lanes/1503/6481535e/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Future.cs:686
2015-05-15 16:47:19.791 namespace[4678:182349] critical:   at System.Threading
.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/1503/6481535e/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2523
2015-05-15 16:47:19.792 namespace[4678:182349] critical:   at System.Threading.Tasks.Task.ExecutionContextCallback (object) [0x00007] in /Users
/builder/data/lanes/1503/6481535e/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2887
2015-05-15 16:47:19.792 namespace[4678:182349] critical:   at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext,System.Threading.ContextCallback,object) [0x00027] in /Users/builder/data/lanes/1503/6481535e/source/mono/mcs/class/corlib/System.Threading/ExecutionContext.cs:242
2015-05-15 16:47:19.792 namespace[4678:182349] critical:   at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool) [0x00000] in /Users/builder/data/lanes/1503/6481535e/source/mono/mcs/class/corlib/System.Threading/ExecutionContext.cs:228
2015-05-15 16:47:19.793 namespace[4678:182349] critical:   at System.Threading.Tasks.Task.ExecuteWithThreadLocal (System.Threading.Tasks.Task&) [0x0005f] in /Users/builder/data/lanes/1503/6481535e/source/mono/external/referencesource/mscorlib/system/threading/
Tasks/Task.cs:2848
2015-05-15 16:47:19.793 namespace[4678:182349] critical:   at System.Threading.Tasks.Task.ExecuteEntry (bool) [0x0006f] in /Users/builder/data/lanes/1503/6481535e/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2781
2015-05-15 16:47:19.793 namespace[4678:182349] critical:   at System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () [0x00000] in /Users/builder/data/lanes/1503/6481535e/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2728
2015-05-15 16:47:19.794 namespace[4678:182349] critical:   at System.Threading.ThreadPool.<UnsafeQueueCustomWorkItem>m__0 (object) [0x00000] in /Users/builder/data/lanes/1503/6481535e/source/mono/mcs/class/corlib/System.Threading/ThreadPool.cs:258
2015-05-15 16:47:19.794 namespace[4678:182349] critical:   at (wrapper runtime-invoke) <Module>.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <IL 0x00062, 0xffffffff>
2015-05-15 16:47:19.794 namespace[4678:182349] critical: 
Native stacktrace:

2015-05-15 16:47:19.795 namespace[4678:182349] critical: 
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

Activity Log

<entry>
    <record>1054</record>
    <time>2015/05/15 23:29:58.111</time>
    <type>Error</type>
    <source>Editor or Editor Extension</source>
    <description>System.InvalidCastException: Unable to cast object of type &apos;Xamarin.VisualStudio.Debugger.AD7DocumentContext&apos; to type &apos;Microsoft.VisualStudio.Debugger.Interop.IDebugDocumentContext2&apos;.&#x000D;&#x000A;   at System.StubHelpers.InterfaceMarshaler.ConvertToManaged(IntPtr pUnk, IntPtr itfMT, IntPtr classMT, Int32 flags)&#x000D;&#x000A;   at Microsoft.VisualStudio.Debugger.Interop.IDebugStackFrame2.GetDocumentContext(IDebugDocumentContext2&amp; ppCxt)&#x000D;&#x000A;   at Microsoft.VisualStudio.Debugger.Parallel.Common.DocumentContext.GetFileNameAndPath()&#x000D;&#x000A;   at Microsoft.VisualStudio.Debugger.Parallel.UI.ThreadMarkerGenerator.LocationMatchesTagger(DocumentContext location, MarkerTagger tagger)&#x000D;&#x000A;   at Microsoft.VisualStudio.Debugger.Parallel.UI.ThreadMarkerGenerator.&lt;&gt;c__DisplayClass1.&lt;GetMarkersForTagger&gt;b__0(ThreadMarker marker)&#x000D;&#x000A;   at System.Linq.Enumerable.WhereListIterator`1.MoveNext()&#x000D;&#x000A;   at Microsoft.VisualStudio.Debugger.Parallel.Extension.MarkerTagger.&lt;GenerateTagList&gt;d__a.MoveNext()&#x000D;&#x000A;   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)&#x000D;&#x000A;   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)&#x000D;&#x000A;   at Microsoft.VisualStudio.Debugger.Parallel.Extension.MarkerTagger..ctor(ITextBuffer buffer, ITextDocument document)&#x000D;&#x000A;   at Microsoft.VisualStudio.Debugger.Parallel.Extension.MarkerTaggerProvider.CreateTagger[T](ITextBuffer buffer)&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.GatherTaggers(ITextBuffer textBuffer)</description>
  </entry>
</activity>
like image 403
ClintL Avatar asked May 16 '15 00:05

ClintL


1 Answers

I know a lot of time have passed from your question but it was one of the few places where I was able to find similar problem (like mine), so I just wanted to share what resolved it in my case.

The problem:

I was getting the exception in different methods that use the database connection from different threads and that led me to believe that SQLite in iOS is for some reason not thread safe, like Android and WinRT (I am using the same code which has some locks and mutexes but methods using deferred queries were causing the issue after the lock is released).

So what fixed it for me was using additional parameter in the connection constructor that enables thread safety of SQLite (Or at least that's what I think is happening :) )

The solution:

var connection = new SQLiteConnection(    
  new SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS(),
  sqliteFilename,
  openFlags: SQLiteOpenFlags.ReadWrite|SQLiteOpenFlags.FullMutex|SQLiteOpenFlags.Create,
  storeDateTimeAsTicks: true);

The important thing here is the flag - FullMutex which I assume is not turned on by default in iOS unlike in Android and WinRT

Hope it helps somebody else, and happy coding to all ;)

like image 127
kirotab Avatar answered Sep 22 '22 14:09

kirotab