Closed AceCoderLaura closed 5 years ago
This is a native crash, not an exception, so nothing is thrown. You can attach lldb
to the process but it's a bit harder (different debugger and native code) and it's not your code.
Your best bet is to put a breakpoint on the last managed frame
2019-03-20 16:48:12.636936+1100 Adapt.Presentation.Xivic.iOS[7868:101522] critical: at Adapt.Data.MonoSQLite.MonoSQLiteCommand.ExecuteReader () [0x00000] in C:\AdaptSource\src\Adapt.Xamarin.Shared\SQLiteInjectable.cs:110
and see the state of your objects. Something (the input) is causing sqlite
to crash. It's might be the query (being prepared) or it might be related to how the session was configured (i.e. earlier).
The symbolicated crash report would also help. It will give more some ideas of what the other threads are doing, e.g. do you call sqlite from multiple thread? did you configure your session as such ?
Finally it's possible that sqlite would have written something into the device logs before crashing, e.g. an assert. Reading the logs might include the clue why the application crashed.
Alright I guess I'll dig a bit more in the managed code for answers. I was not aware of device logs and symbolic crash reports until now, I'll look into those next and forward them here if there might be anything helpful.
The last command to go in before the native library crashes is pragma table_info('TableSchema.TableName')
. Perhaps the table does not exist? Sometimes this call succeeds sometimes it doesn't.
The device log doesn't appear to contain any new information other than the SIGSEGV message I already have. I can't get to the symbolic crash report since the simulator appears to hide the menu items in the settings that allow you to get access to them.
Okay I've found that there is no specific call that causes this problem. It appears to be completely random.
I can have one call succeed and another fail on the same thread. But I can also have multiple calls succeed on different threads. It seems like the thread the statement executes on is irrelevant.
I attached LLDB and found the exception EXC_BAD_ACCESS (code=1, address=0x1b00000025)
.
I also retrieved the stack trace:
sqlite3ExprListAppend 0x000000011fa5a9f5
yy_reduce 0x000000011fa3da54
sqlite3RunParser 0x000000011f9d4727
sqlite3LockAndPrepare 0x000000011f9d27bd
sqlite3_prepare 0x000000011f9d1fbc
I had no clue but it did look like a threading issue. Your additional details makes me even more convinced of it.
SqliteConnection.SetConfig(SQLiteConfig.Serialized);
This is the safest option to use since it (sqlite) will deal with any threading issue.
The simulator does produce crash reports (see Console.app) but they are not very useful (the JIT is used). You'll get a better (more useful one) one when running your application on a device;
From lldb you want to get a backtrace of all threads (not just the current one).
It appears that calling Mono.Data.Sqlite.SqliteConnection.SetConfig(Mono.Data.Sqlite.SQLiteConfig.Serialized);
fixes the issue, thanks.
I wish the library had told me the problem from the get-go 🙁
Apple builds/ships libsqlite in the OS as a multithreaded by default (i.e. it puts your in charge). However this library has a mode that can take care of multithreading (by serializing requests) for you.
In general you are responsible to protect the state of your data when using multi-threading. Several types are not thread-safe, limited to the main thread (mostly UI) or to the thread that created them.
Steps to Reproduce
Mono.Data.Sqlite.SqliteCommand.ExecuteReader()
Expected Behavior
Executes the reader.
Actual Behavior
Get a SIGSEGV while executing native code.
Environment
Build Logs
JetBrainsLog.ReSharperBuild_2019_03_20_05_47_07_6136.log.zip
Stack Trace
PS: I get these native errors all the time. How do I break when one is thrown? It would really help me write better issue submissions.