Details of 0xdead100c and suspension handling #1369
Replies: 2 comments 1 reply
-
Hello @tomhamming, According to Understanding the exception types in a crash report,
The database must be stored in a shared container for this exception to be raised. The "SQLite database lock" is assumed to be an EXCLUSIVE lock, as defined by File Locking And Concurrency In SQLite Version 3. "Suspension" refers to the entrance into the suspended state as defined by Managing your app’s life cycle.
According to the above definitions, having an open connection is not a problem, as long as it does not hold any lock when the app becomes suspended. The GRDB way (experimental) is to prevent connections from acquiring new locks, but allowing connections to release locks. Precisely speaking, after a suspension notification has been posted, connections are interrupted - this interruption rollbacks all transactions that are busy performing database operations. Some connections are not busy at the moment the notification is posted, and those are not interrupted. They will accept statements that release locks (such as Since you are "looking at doing something similar in your app", please make sure you consider the GRDB technique with a grain of salt. It's just the best I was able to ship, based on the 0xdead10cc prevention discussion.
According to the theory, you can reproduce 0xdead10cc if you open a transaction, perform one write (so that the EXCLUSIVE lock is acquired), and don't release the transaction until the app to become suspended. It's been a long time I haven't played with such a setup. I actually advise strongly to avoid storing SQLite databases in a shared container :-) |
Beta Was this translation helpful? Give feedback.
-
Thanks for the detailed answer here! I have been working to correctly understand the conditions under which this exception occurs for my app. I finally figured out that the reason I never saw the issue was that I use a variant of my app that doesn't actually store its data in an App Group folder. Beta testers reporting the issue are on a variant that does. This came up because I've been working on caching prepared SQLite statements, which ends up being a huge performance boost in some situations. I started getting these increased reports of crashing on app suspension when I rolled it out to beta builds. And now I've confirmed that in addition to happening when there's an open transaction when the app is suspended, Also, you can reproduce
|
Beta Was this translation helpful? Give feedback.
-
Hello! I am looking at how GRDB deals with the
0xdead100c
error, as described in the docs under Sharing a Database. I found the implementation aroundisSuspended
inDatabase.swift
- marking databases as suspended in response toDatabase.suspendNotification
, interrupting current operations at the time of suspend, and blocking new write operations while suspended. I am looking at doing something similar in my app, and I have a couple of questions.First, judging by the fact that your handling deals with read/write operations like
UPDATE
statements and transactions, the issue is about those operations and not simply about having an open connection. Is this true? Or do all connections need to be closed on suspend?Second, does this crash happen on devices in Development mode? I use TestFlight for betas in my app and I often get reports of iOS popping up a crash report when my app is suspended. When I look at those reports, the termination reason is
0xdead100c
. But I personally use TestFlight builds of my app constantly, and I have never seen a crash report on app suspend. And my device is in Development mode.Beta Was this translation helpful? Give feedback.
All reactions