Native crash (SIGSEGV in getSuggestionsNative) when typing with a multilingual secondary language

Geschlossen
#759 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
25/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Aktiv
Tech-Stack
android, cpp, kotlin
Bereich
mobile

Rechercherichtung

Start with DictionaryFacilitatorImpl.getSuggestionResults(), where secondary-dictionary queries run in scope.launch and are awaited for 120 ms, then BinaryDictionary.getSuggestions(), where only getTraverseSession() is synchronized and the native call is not. The work is to confirm that overlapping queries share one DicTraverseSession and then make access to that session safe; the reporter already has a candidate fix. Done means no SIGSEGV under overlapping queries, which needs a device or a concurrency reproduction.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Describe the bug
With a secondary language added via Multilingual typing (German + English (US), both main dictionaries installed), the keyboard process sometimes crashes in native code (SIGSEGV, null pointer dereference in libjni_latinime.so). For us it happened right after tapping the clipboard suggestion and when typing fast.

Backtrace (shortened):

F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x11 in tid 10828 (DefaultDispatch)
F DEBUG   : Cause: null pointer dereference
F DEBUG   :   #00..#04 libjni_latinime.so
F DEBUG   :   #11 com.android.inputmethod.latin.BinaryDictionary.access$getSuggestionsNative
F DEBUG   :   #24 com.android.inputmethod.latin.BinaryDictionary.getSuggestions
F DEBUG   :   #30 helium314.keyboard.latin.dictionary.ReadOnlyBinaryDictionary.getSuggestions
F DEBUG   :   #35 helium314.keyboard.latin.dictionary.DictionaryCollection.getSuggestions
F DEBUG   :   #38 helium314.keyboard.latin.DictionaryFacilitatorImpl.getSuggestions
F DEBUG   :   #49 helium314.keyboard.latin.DictionaryFacilitatorImpl$getSuggestionResults$1.invokeSuspend
F DEBUG   :   #53 kotlinx.coroutines.DispatchedTask.run

Cause (from reading the code)
DictionaryFacilitatorImpl.getSuggestionResults() queries the secondary dictionary groups in scope.launch {} on a background thread and waits for them only up to await(120, TimeUnit.MILLISECONDS) (reduced from 500 ms in 05023da). If a query takes longer, the next keystroke starts a new query on the same dictionary while the previous one is still running.

Both queries use the same DicTraverseSession (same session id). Its Java buffers (mInputCodePoints, mPrevWordCodePointArrays, ...) and the native session are shared. BinaryDictionary.getSuggestions() only synchronizes the session lookup in getTraverseSession(), not the native call, so two threads can run getSuggestionsNative() on the same native session at the same time.

Fix that works for us
Hold a lock on the session for the whole query in BinaryDictionary.getSuggestions():

val session = getTraverseSession(sessionId)
synchronized(session) {
    // fill the session buffers, call getSuggestionsNative(..., session.getSession(), ...), read the results
}

(and pass session.getSession() instead of calling getTraverseSession(sessionId) a second time). We haven't seen the crash since. I can send a PR once we've tested it a bit longer.

To Reproduce

  1. Languages & Layouts → German → Multilingual typing → add English (US). Install the main dictionaries for both.
  2. Type fast, or copy some text and tap the clipboard suggestion right away.
  3. Occasionally the keyboard crashes and restarts. It depends on timing, so it doesn't happen every time.

Expected behavior
No crash.

App version & Flavor
Found in GlassType, my fork based on LeanType 4.3.0 (d634e26), standard flavor. BinaryDictionary.getSuggestions() is unchanged in current main (0e673e1), and getSuggestionResults() now waits even shorter (120 ms).

Device Info

  • Model: Samsung Galaxy S23 Ultra (SM-S918B)
  • OS version: Android 17
Vorherrschende Sprache
Kotlin
Sterne
1k
Forks
59
Ø Merge
14 Std. 9 Min.
Gemergte PRs (30 T.)
56

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus LeanBitLab/LeanType

Alle Issues in LeanBitLab/LeanType

Ähnliche Issues

Weitere Issues zu Kotlin

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.