signalapp / signalapp/Signal-Android

[Bug] VC 162700 crashed with a `SQLiteDatabaseCorruptException` upon `keyevent KEYCODE_POWER`.

Open
#14,481 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
29.4k
Forks
6.9k
PR merge metrics
No merged PRs in 30d

Description

Guidelines
  • I have searched searched open and closed issues for duplicates
  • I am submitting a bug report for existing functionality that does not work as intended
  • This isn't a feature request or a discussion topic
Bug description

Whilst I locked, then unlocked, ^1 then locked my device: ^2

#!/system/bin/sh
input keyevent 82 && \
sleep 1 && \
input keyevent 66 && \
sleep 1 && \
input text $PIN && \
sleep 1 && \
input keyevent 66 && \
sleep 1 && \
input keyevent KEYCODE_POWER && \
sleep 1 && \
input keyevent 82 && \
sleep 1 && \
input keyevent 66 && \
sleep 1 && \
input text $PIN && \
sleep 1 && \
input keyevent 66 && \
sleep 1 && \
input keyevent 82 && \
sleep 1 && \
input keyevent 66 && \
sleep 1 && \
input text $PIN && \
sleep 1 && \
input keyevent 66 && \
sleep 1 && \
input keyevent KEYCODE_POWER

…in the background, PT4S after Spotify crashed:

12-11 23:37:27.931 25346 25346 E AndroidRuntime: FATAL EXCEPTION: main
12-11 23:37:27.931 25346 25346 E AndroidRuntime: Process: com.spotify.music, PID: 25346
12-11 23:37:27.931 25346 25346 E AndroidRuntime: java.lang.IllegalArgumentException: Tmp detached view should be removed from RecyclerView before it can be recycled: bl60{d007236 position=0 id=-1, oldPos=-1, pLpos:-1 tmpDetached no parent} com.spotify.nowplaying.carousel.CarouselView{8b484a3 VFED..... ......ID 0,0-518,59 #7f0b1238 app:id/tracks_carousel_view}, adapter:p.si60@8829fd7, layout:com.spotify.nowplaying.carousel.CarouselView$1@f60cf90, context:com.spotify.music.SpotifyMainActivity@2aa8306
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at androidx.recyclerview.widget.f.j(SourceFile:270)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at androidx.recyclerview.widget.d.d(SourceFile:122)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at p.m6j.onAnimationEnd(SourceFile:16)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.view.ViewPropertyAnimator$AnimatorEventListener.onAnimationEnd(ViewPropertyAnimator.java:1115)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:708)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.Animator$AnimatorCaller$$ExternalSyntheticLambda1.call(D8$$SyntheticClass:0)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.Animator.callOnList(Animator.java:666)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.Animator.notifyListeners(Animator.java:609)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.Animator.notifyEndListeners(Animator.java:634)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1306)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1566)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:344)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:87)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1416)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1427)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.view.Choreographer.doCallbacks(Choreographer.java:1026)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.view.Choreographer.doFrame(Choreographer.java:951)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1401)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.os.Handler.handleCallback(Handler.java:959)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:100)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.os.Looper.loopOnce(Looper.java:232)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:317)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:8751)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
12-11 23:37:27.931 25346 25346 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:892)

…Signal did:

12-11 23:37:31.835 14195 14360 E AndroidRuntime: FATAL EXCEPTION: signal-unbounded-0
12-11 23:37:31.835 14195 14360 E AndroidRuntime: Process: org.thoughtcrime.securesms, PID: 14195
12-11 23:37:31.835 14195 14360 E AndroidRuntime: android.database.sqlite.SQLiteDatabaseCorruptException: FullCode: 11 | ErrorCode: 11 | ExtendedErrorCode: 0 | Message: database disk image is malformed | ExtraMessage: null
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at net.zetetic.database.sqlcipher.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at net.zetetic.database.sqlcipher.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:929)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at net.zetetic.database.sqlcipher.SQLiteSession.executeForCursorWindow(SQLiteSession.java:871)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at net.zetetic.database.sqlcipher.SQLiteQuery.fillWindow(SQLiteQuery.java:68)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at net.zetetic.database.sqlcipher.SQLiteCursor.fillWindow(SQLiteCursor.java:196)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at net.zetetic.database.sqlcipher.SQLiteCursor.getCount(SQLiteCursor.java:135)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:252)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:291)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.signal.core.util.CursorExtensionsKt.readToSingleLongOrNull(CursorExtensions.kt:92)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.signal.core.util.CursorExtensionsKt.readToSingleLong(CursorExtensions.kt:87)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.thoughtcrime.securesms.database.LogDatabase$LogTable.getSize(LogDatabase.kt:292)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.thoughtcrime.securesms.database.LogDatabase$LogTable.trimToSize(LogDatabase.kt:240)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.thoughtcrime.securesms.ApplicationContext.lambda$initializeLogging$26(ApplicationContext.java:344)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.thoughtcrime.securesms.ApplicationContext.$r8$lambda$B17To4TumdeI5sCSFFUfcQDzPLo(ApplicationContext.java:0)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.thoughtcrime.securesms.ApplicationContext$$ExternalSyntheticLambda72.run(R8$$SyntheticClass:0)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1154)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:652)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at java.lang.Thread.run(Thread.java:1563)
12-11 23:37:31.835 14195 14360 E AndroidRuntime:        at org.signal.core.util.concurrent.SignalExecutors$NumberedThreadFactory$1.run(SignalExecutors.java:100)
Device
  1. #!/usr/bin/env pwsh
    $Object = [Ordered]@{}
    @(
    	'ro.product.brand'
    	'ro.build.product'
    ) | ForEach-Object {
    	$Value = (adb shell "getprop $_").Trim()
    	If ($Value) {
    		$Int64 = 0L
    		$Object[$_] =
    			If ([Long]::TryParse($Value, [Ref]$Int64)) {
    				$Int64
    			} Else {
    				$Value
    			}
    	}
    }
    $Object |
    	ConvertTo-Json -Compress |
    	yq -P
    

  2. ro.product.brand: Fairphone
    ro.build.product: FP5
    
Android version
  1. #!/usr/bin/env pwsh
    $Object = [Ordered]@{}
    @(
    	'ro.build.display.id'
    	'ro.build.fingerprint'
    	'ro.build.version.sdk'
    	'ro.build.version.sdk_full'
    ) | ForEach-Object {
    	$Value = (adb shell "getprop $_").Trim()
    	If ($Value) {
    		$Int64 = 0L
    		$Object[$_] =
    			If ([Long]::TryParse($Value, [Ref]$Int64)) {
    				$Int64
    			} Else {
    				$Value
    			}
    	}
    }
    $Object |
    	ConvertTo-Json -Compress |
    	yq -P
    

  2. ro.build.display.id: FP5.VT2F.C.065.20251016
    ro.build.version.sdk: 35
    
Signal version
  1. #!/usr/bin/env pwsh
    $Package = 'org.thoughtcrime.securesms'
    $DumpSys = adb shell "dumpsys package $Package"
    $Object = [Ordered]@{}
    @{
    	versionCode = 'versionCode=(\d+)'
    	versionName = 'versionName=([^\s]+)'
    }.GetEnumerator() | ForEach-Object {
    	$Match = [RegEx]::Match(
    		$DumpSys,
    		$_.Value,
    		[System.Text.RegularExpressions.RegexOptions]::Multiline
    	)
    	If ($Match.Success) {
    		$Value = $Match.Groups[1].Value
    		$Int64 = 0L
    		$Object[$_.Key] =
    			If ([Long]::TryParse($Value, [Ref]$Int64)) {
    				$Int64
    			} Else {
    				$Value
    			}
    	}
    }
    $Object.installer = (
    	adb shell 'pm list packages -i' |
    		Select-String "^package:$([RegEx]::Escape($Package)) " |
    		ForEach-Object {
    			$_ -replace '^.*installer='
    		}
    )
    $Object |
    	ConvertTo-JSON -Compress |
    	yq -P
    

  2. versionCode: 162700
    versionName: 7.67.1
    
Link to debug log
Original GitHub
debuglogs.org/android/7.67.1/d7baf608cfbeae3ad43c4e9459b2ecd968d131d9a0b7dbc507887ade8ee9c700 user-attachments/files/24116884/d7baf608cfbeae3ad43c4e9459b2ecd968d131d9a0b7dbc507887ade8ee9c700.gz
content:\/\/*.\/signal-log-1765496876319.zip user-attachments/files/24116830/signal-log-1765496876319.zip

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied reproduction sequence and debug logs, then trace the Signal stack through org.thoughtcrime.securesms.database.LogDatabase.kt, ApplicationContext.java, and CursorExtensions.kt. Compare the SQLite corruption path with the separate Spotify crash; done should mean the reported lock/unlock sequence no longer produces the Signal database crash.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin, sqlite
Domain
databases, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.