sqlcipher / android-database-sqlcipher

Android SQLite API based on SQLCipher
https://www.zetetic.net/sqlcipher/sqlcipher-for-android/
Other
2.73k stars 564 forks source link

Repetitive crashes on 4.5.3: net.sqlcipher.CursorWindow.<init> & native_init #618

Open cokeperez opened 1 year ago

cokeperez commented 1 year ago

A few weeks ago we upgraded the version of SQLCipher in our application from 4.5.1 to 4.5.3. Since we updated the SQLCipher version, we are receiving dozens of crashes related to cursors on a daily basis.

Some info about the problem:

The two crashes that happen are:

net.sqlcipher.CursorWindow.\<init> (two different causes)

85% on Android 4 (although this version only accounts for 20% of our network). These users on API19 (Android 4.4.2 and 4.4.4.4) all have older Samsung devices (Galaxy Tab 3/4/E). The remaining 15% are split between Android 9, 10 and 11, so the problem is not unique to Android 4 but does seem to be more prevalent on this version.

Caused by android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. 
       at android.database.CursorWindow.<init>(CursorWindow.java:109)
       at android.database.CursorWindow.<init>(CursorWindow.java:100)
       at android.database.CursorWindow.<init>(CursorWindow.java:131)
       at net.sqlcipher.CursorWindow.<init>(CursorWindow.java:67)
       at net.sqlcipher.database.SQLiteCursor.fillWindow(SQLiteCursor.java:301)
       at net.sqlcipher.database.SQLiteCursor.getCount(SQLiteCursor.java:292)
       at net.sqlcipher.AbstractCursor.moveToPosition(AbstractCursor.java:178)
       at net.sqlcipher.AbstractCursor.moveToFirst(AbstractCursor.java:222)
       at android.database.CursorWrapper.moveToFirst(CursorWrapper.java:65)
       at org.frogtek.database.wrapper.Cursor.moveToFirst(Cursor.java:50)
       ...
       ...
Caused by android.database.CursorWindowAllocationException: Could not allocate CursorWindow '<unnamed>' of size 2097152 due to error -12.
       at android.database.CursorWindow.nativeCreate(CursorWindow.java)
       at android.database.CursorWindow.<init>(CursorWindow.java:139)
       at android.database.CursorWindow.<init>(CursorWindow.java:120)
       at android.database.CursorWindow.<init>(CursorWindow.java:162)
       at net.sqlcipher.CursorWindow.<init>(CursorWindow.java:67)
       at net.sqlcipher.database.SQLiteCursor.fillWindow(SQLiteCursor.java:301)
       at net.sqlcipher.database.SQLiteCursor.getCount(SQLiteCursor.java:292)
       at net.sqlcipher.AbstractCursor.moveToPosition(AbstractCursor.java:178)
       at net.sqlcipher.AbstractCursor.moveToFirst(AbstractCursor.java:222)
       at android.database.CursorWrapper.moveToFirst(CursorWrapper.java:75)
       ...
       ...

net.sqlcipher.CursorWindow.native_init

99% on Android 4

Fatal Exception: java.lang.IllegalStateException: Couldn't init cursor window
       at net.sqlcipher.CursorWindow.native_init(CursorWindow.java)
       at net.sqlcipher.CursorWindow.<init>(CursorWindow.java:72)
       at net.sqlcipher.database.SQLiteCursor.fillWindow(SQLiteCursor.java:301)
       at net.sqlcipher.database.SQLiteCursor.getCount(SQLiteCursor.java:292)
       at net.sqlcipher.AbstractCursor.moveToPosition(AbstractCursor.java:178)
       at net.sqlcipher.AbstractCursor.moveToFirst(AbstractCursor.java:222)
       at android.database.CursorWrapper.moveToFirst(CursorWrapper.java:65)
       ...
       ...

We have released a new version of our app by downgrading the SQLiteCipher version and the crashes have stopped.

What do you think could be happening, any idea how to solve it?

Thanks a lot for your help!

developernotes commented 1 year ago

Hi @cokeperez,

In terms of the changes directly within SQLCipher for Android between 4.5.1 and 4.5.3, those may be found here along with the SQLCipher core changes here changes. Given the changes it is particularly strange that reverting to 4.5.1 resolved the errors.

We have not been able to reproduce it.

Do you have the same devices in order to attempt to reproduce this error?

Based on the error message, it appears the library is failing to allocate additional memory on those specific devices when returning the cursor. If you are not customizing the cursor window allocation, you would be using the default configuration. You can customize this for your application, a few examples may be found here and here. It is worth investigating whether an adjustment to the allocation improves the behavior of the application.

cokeperez commented 1 year ago

Thank you for your response @developernotes.

We have the same devices and have access to full copies of the user databases, but even so we have not been able to reproduce it. Our app is a point of sale that is usually running more than 12 hours a day on the devices so it is complicated to replicate exactly the same conditions of the users. The same query that causes a user to crash is executed hundreds of times during the day without problems, with the user repeating the same flow of activities.

This week I will try running the tests you link me to on the devices that are failing, to see if we can reproduce it. I also check out the option to customize the cursor window allocation and generate a test version.