Fixed
Status Update
Comments
an...@gmail.com <an...@gmail.com> #2
Hi. Thanks for reporting this. Fixed in alpha-04
yb...@google.com <yb...@google.com>
da...@google.com <da...@google.com> #3
Project: platform/frameworks/support
Branch: androidx-main
commit e782987543a9f8ccd485e970ddc74564b24378db
Author: Vighnesh Raut <vighnesh.raut13@gmail.com>
Date: Mon Jan 02 15:27:40 2023
fix: tab row crashes when only 1 tab is added
Bug: b/264018028
Test: Added unit test
Change-Id: I6381dbac304fc1d69d3708c6655f8b595668e93f
M tv/tv-material/src/androidTest/java/androidx/tv/material/TabRowTest.kt
M tv/tv-material/src/main/java/androidx/tv/material/TabRow.kt
https://android-review.googlesource.com/2373449
Branch: androidx-main
commit e782987543a9f8ccd485e970ddc74564b24378db
Author: Vighnesh Raut <vighnesh.raut13@gmail.com>
Date: Mon Jan 02 15:27:40 2023
fix: tab row crashes when only 1 tab is added
Bug:
Test: Added unit test
Change-Id: I6381dbac304fc1d69d3708c6655f8b595668e93f
M tv/tv-material/src/androidTest/java/androidx/tv/material/TabRowTest.kt
M tv/tv-material/src/main/java/androidx/tv/material/TabRow.kt
an...@gmail.com <an...@gmail.com> #4
deleted
da...@google.com <da...@google.com> #5
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.tv:tv-material:1.0.0-alpha04
an...@gmail.com <an...@gmail.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?
da...@google.com <da...@google.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).
an...@gmail.com <an...@gmail.com> #8
That makes sense. I will update the app as soon as the new Room will be released and let you know if it helps.
Description
Version used: 2.1.0-alpha03
Devices/Android versions reproduced on: All devices. minSdk = 21. Most devices are Samsung (~90%)
I am getting tons of crashes and I am not able to reproduce them. Please see to attached stacktrace. I am using a default migration (drop everything -> recreate everything):
@Provides
@PerApplicationScope
fun provideDatabase(application: Application): VintedDatabase {
val builder = Room.databaseBuilder(
application,
VintedDatabase::class.java,
"vinted_database.db"
)
.fallbackToDestructiveMigration()
if (Debug.isDebuggerConnected()) {
builder.allowMainThreadQueries()
}
return builder.build()
}
The application is crashing on random DAO calls in various places in the app. There is a similar issue:
This generated code looks very stable. Also, everything at FrameworkSQLiteOpenHelper is synchronized, and I don't get how is possible to close DB during migration. But one thing caught my eye there:
FrameworkSQLiteDatabase getWrappedDb(SQLiteDatabase sqLiteDatabase) {
FrameworkSQLiteDatabase dbRef = mDbRef[0];
if (dbRef == null) {
dbRef = new FrameworkSQLiteDatabase(sqLiteDatabase);
mDbRef[0] = dbRef;
}
return mDbRef[0];
}
Just hypothetically, what if someone gets a DB through `FrameworkSQLiteOpenHelper.getWritableDatabase()` and closes immediate, like:
FrameworkSQLiteOpenHelper.getWritableDatabase().close()
Then DB instance will be closed and opening a new writable database gives a new SQLiteDatabase instance. But getWrappedDb returns an old one because the ref was not cleared because DB was closed directly instead of FrameworkSQLiteOpenHelper. Maybe some safety is needed here, like:
if (dbRef != null && dbRef.mDelegate != sqLiteDatabase) {
//try to close old instance anyway to avoid memory leak
dbRef.close()
dbRef = null
}
//rest code
Need to mention, DAO requests could be done on a few IO threads. Maybe Single thread environment would be better?