Disk-persisted data can race during SDK re-init
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
Línea de trabajo
Rastrea la reinicialización desde Sentry.init hasta Scopes.close(boolean) y, después, inspecciona PersistingScopeObserver, CacheUtils, PersistingOptionsObserver y EnvelopeCache. Concéntrate primero en el QueueFile compartido de breadcrumbs.json y en el comportamiento de apagado del executor antiguo; done debería demostrar que la reinicialización no puede solapar operaciones de disco ni perder datos persistidos de scope, options, session o envelope.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
During SDK re-init (Sentry.init while already enabled), previous and new SDK lifecycles can concurrently read/write the same on-disk paths under cacheDirPath. On restart, Scopes.close(true) shuts the old executor down asynchronously rather than blocking, so old flush/session/envelope work can still touch files while the new init writes the same locations.
Impact: corrupted or lost scope/options/session state used for ANR/exit enrichment and crash recovery; possible lost breadcrumbs.
Why this races
- Re-init path closes previous scopes with
isRestarting=true, then continues init immediately:Sentry.init→Scopes.close(true) - On restart the old executor is closed via a submitted task (non-blocking), so pending disk work can still run briefly:
Scopes.close(boolean) - New init then enqueues session move/finalize, options observers, and scope-cache reset on the new executor against the same cache paths:
notifyOptionsObservers/movePreviousSession/finalizePreviousSession - Fixed filenames are not isolated per SDK lifecycle / run id
Disk-backed surfaces that share paths across re-init
Scope cache (.scope-cache/, via PersistingScopeObserver + CacheUtils):
breadcrumbs.json— singleQueueFile; old executor may still add/sync while new initresetCache()clears/syncs the same fileuser.json,tags.json,extras.json,contexts.json,request.json,level.json,fingerprint.json,transaction.json,trace.json,replay.json— plain overwrite/deleteof fixed names; no atomic replace- New init explicitly
resetCache()after options observers run, which collides with any late old-lifecycle flushes
Options cache (.options-cache/, via PersistingOptionsObserver and Android PersistingOptionsCacheGenerationObserver):
release.json,proguard-uuid.json,sdk-version.json,environment.json,dist.json,tags.json,replay-error-sample-rate.json,app-last-update-time.json- Written on every init via options observers; same fixed paths, non-atomic
FileOutputStreamoverwrite
Session / envelope cache (EnvelopeCache, Android AndroidEnvelopeCache):
session.json/previous_session.json— move + rewrite on session start; previous-session finalize also reads/deletes these*.envelopeoffline cache — old client flush vs new client store/send against same dir- crash markers:
last_crash,.sentry-native/last_crash,startup_crash(outbox) - Android ANR last-reported markers under cache dir
Other fixed-path / shared-dir writers (same cacheDirPath, lifecycle-overlapping on re-init):
- App-start profiling config file rewritten on init (
Sentry.handleAppStartProfilingConfig) - Profiling traces dir cleanup on init vs in-flight profile finalization
- Session Replay dirs (
replay_<id>/) under cache dir (ReplayCache); cleanup walks cache dir on integration start - ANR profile
QueueFiles under cache dir (AnrProfileManager/ rotation helper already documents concurrentQueueFilerisk)
Highest-confidence race today
Scope persistence breadcrumbs: single shared breadcrumbs.json QueueFile, old executor still draining adds while new init clears it in resetCache(), with only executor ordering (not cross-lifecycle isolation) as the safety net.
Related
- Closed perf work on scope persistence writes: https://github.com/getsentry/sentry-java/issues/5714
- Closed re-init executor timeout work: https://github.com/getsentry/sentry-java/issues/5715
- Closed “don’t wait when SDK is reinitialized”: https://github.com/getsentry/sentry-java/issues/3162
Unknowns
- Whether this has been observed in production beyond code inspection / reasoning about re-init
- How often customer/integration re-init hits the overlapping-executor window in practice
Raised by Markus Hintersteiner during SDK re-init / disk-persistence discussion.
Requested by markus.hintersteiner.
--
- Lenguaje dominante
- Kotlin
- Estrellas
- 1.4k
- Forks
- 478
- Merge medio
- 2 d 20 h
- PR fusionados (30 d)
- 71
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de getsentry/sentry-java
-
Improvement Java Platform: Android Platform: Java
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
getsentry/sentry-java#6145 · 1 comentario · 1 asignado ·
-
Bug Java Platform: Android Platform: Java
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
getsentry/sentry-java#6138 · 1 comentario ·
-
Feature Java Platform: Java Spans
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
getsentry/sentry-java#5984 · 1 comentario ·
-
Android Task Traces
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
getsentry/sentry-java#5376 · 1 comentario ·
-
Android Docs Errors
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
getsentry/sentry-java#5375 · 1 comentario ·
Todos los issues de getsentry/sentry-java
Issues similares
-
[Bug] 统计页面无法重置token和汇率 Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
AAswordman/Operit#1265 · 3 comentarios ·
-
Tambahkan bahasa Indonesia Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
acristescu/OnlineGo#216 ·
-
Remove custom segment colors Abiertoenhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
libre-tube/LibreTube#8803 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
status: waiting-for-triage type: bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
spring-projects/spring-security#19781 ·