getsentry / getsentry/sentry-java
Disk-persisted data can race during SDK re-init
還沒有人認領這個 Issue。
- 主要語言
- Kotlin
- 星號
- 1.4k
- 分支
- 478
- 平均合併
- 3 天 4 小時
- 30 天內合併 PR
- 72
描述
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.
--
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
追蹤從 Sentry.init 到 Scopes.close(boolean) 的重新初始化流程,接著檢查 PersistingScopeObserver、CacheUtils、PersistingOptionsObserver 和 EnvelopeCache。首先聚焦於共用的 breadcrumbs.json QueueFile 以及舊 executor 的關閉行為;done 應證明重新初始化不會讓磁碟操作重疊,也不會遺失已持久化的 scope、options、session 或 envelope 資料。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- java, kotlin
- 領域
- mobile, tooling
- Issue 類型
- 缺陷
- 難度
- 5/5
- 預估耗時
- 一週以上
- 活躍度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100