Fixed
Status Update
Comments
da...@google.com <da...@google.com> #2
Also noticed that crash happens ~7-8 times per user.
el...@google.com <el...@google.com>
da...@google.com <da...@google.com>
ap...@google.com <ap...@google.com> #3
It looks like Room 2.1.0 is not using androidx.sqlite:sqlite-framework:2.0.1 which should contain a fix for the situation you are just describing. The snippet of code you pasted for getWrappedDb() is different than what is in the head of the repo. See: https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/persistence/db-framework/src/main/java/androidx/sqlite/db/framework/FrameworkSQLiteOpenHelper.java#152
da...@google.com <da...@google.com>
pr...@google.com <pr...@google.com> #4
This is a proper fix IMO. However, I can't find the package in http://maven.google.com/androidx/ . There I found only 2.0.0. Where else should I look? Also, the latest room 2.1.0-alpha4 does not include this version as well.
jo...@gmail.com <jo...@gmail.com> #5
It seems sqlite-framework:2.0.1 never made it to maven.google.com , we'll release it soon along with Room 2.1.0-alpha05 which should correctly depend on it. Sorry for the inconvenience.
da...@google.com <da...@google.com> #6
Thanks! I will definitely try the newest room version.
However, more I look at the code, more I believe the problem is elsewhere. If the migration fails, there will be no `SQLiteDatabase` and no `getWrappedDb(db)`. According to the code of `SQLiteOpenHelper`, there should be only one query before migration. The list of queries should be:
PRAGMA user_version;
DROP TABLE IF EXISTS `tracking_events` <--- this fails due closed database
DROP TABLE IF EXISTS `items` <-- never happens
More findings caught by my eye:
- I tried to make sure all DAO queries happen on a single thread. No success.
- The crash happens on a small number of users, but users get many crashes. I am afraid the user is unable to launch the app.
- Most crashes come from Samsung devices. But `SQLiteOpenHelper` class were not changed. All lines of stacktrace matches.
- `SQLiteOpenHelper` was constructed only once for `vinted_database.db`. However, meminfo shows something I don't understand:
DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 512 61 104/135/8 /data/user/0/lt.ito.md/databases/vinted_database.db
4 8 0/0/0 (attached) temp
4 512 25 35/14/2 /data/user/0/lt.ito.md/databases/vinted_database.db (3)
Looks like database was opened two times. There was opened more databases in my app, but no one appears in this list.
What else I could check?
However, more I look at the code, more I believe the problem is elsewhere. If the migration fails, there will be no `SQLiteDatabase` and no `getWrappedDb(db)`. According to the code of `SQLiteOpenHelper`, there should be only one query before migration. The list of queries should be:
PRAGMA user_version;
DROP TABLE IF EXISTS `tracking_events` <--- this fails due closed database
DROP TABLE IF EXISTS `items` <-- never happens
More findings caught by my eye:
- I tried to make sure all DAO queries happen on a single thread. No success.
- The crash happens on a small number of users, but users get many crashes. I am afraid the user is unable to launch the app.
- Most crashes come from Samsung devices. But `SQLiteOpenHelper` class were not changed. All lines of stacktrace matches.
- `SQLiteOpenHelper` was constructed only once for `vinted_database.db`. However, meminfo shows something I don't understand:
DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 512 61 104/135/8 /data/user/0/
4 8 0/0/0 (attached) temp
4 512 25 35/14/2 /data/user/0/
Looks like database was opened two times. There was opened more databases in my app, but no one appears in this list.
What else I could check?
lu...@gmail.com <lu...@gmail.com> #7
This type of behavior can also be seen when the corrupted database recovery mechanism is not correctly performed. Something that sqlite-framework:2.0.1 also fixed over its previous version.
See this patch and specifically the test in it:https://android.googlesource.com/platform/frameworks/support/+/611c90a4711670f8fe0d66ff2eaa8cb0266422d5
When the DB is corrupted (outside your control, and very little to do really) then the DB is immediately closed in hopes of creating a new DB (and a new object). What ends up happening is the corrupted object is still used causing the first db operation to fail (in this case a migration or that DROP TABLE IF EXISTS).
See this patch and specifically the test in it:
When the DB is corrupted (outside your control, and very little to do really) then the DB is immediately closed in hopes of creating a new DB (and a new object). What ends up happening is the corrupted object is still used causing the first db operation to fail (in this case a migration or that DROP TABLE IF EXISTS).
Description
Component useds: androidx.room:room-ktx, androidx.room:room-testing Version used: 2.6.1 Devices/Android versions reproduced on: Robolectric
The definition of
Room.inTransaction()
is:This opens the db even if it wasn't previously open and doesn't close it. This is almost always going to be fine in production, but in tests it can cause a db leak, which is especially painful since it's called by room-internal code.
Since it's
open
, in my project I simply overrode it to bewhich resolved the issue and is similar to a check that most, but not all, room-internal code does anyway.
Would be great to have this catch in the framework though, to prevent this issue for others