Disk-persisted data can race during SDK re-init
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
調査の方向性
Sentry.init から Scopes.close(boolean) までの再初期化を追跡し、次に PersistingScopeObserver、CacheUtils、PersistingOptionsObserver、EnvelopeCache を調査します。まず共有されている breadcrumbs.json QueueFile と古い executor のシャットダウン動作に注目してください。done では、再初期化によってディスク操作が重複して実行されたり、永続化された scope、options、session、envelope のデータが失われたりしないことを示す必要があります。
索引モデルが issue の本文から書いたものです。
説明
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.
--
- 主要言語
- Kotlin
- スター
- 1.4k
- フォーク
- 478
- 平均マージ
- 2日 20時間
- マージ済み PR(30日)
- 71
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
getsentry/sentry-java のほかの issue
-
Improvement Java Platform: Android Platform: Java
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
getsentry/sentry-java#6145 · コメント 1 件 · 担当者 1 名 ·
-
Bug Java Platform: Android Platform: Java
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
getsentry/sentry-java#6138 · コメント 1 件 ·
-
Feature Java Platform: Java Spans
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
getsentry/sentry-java#5984 · コメント 1 件 ·
-
Android Task Traces
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
getsentry/sentry-java#5376 · コメント 1 件 ·
-
Android Docs Errors
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
getsentry/sentry-java#5375 · コメント 1 件 ·
getsentry/sentry-java の issue をすべて見る
似ている issue
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
libre-tube/LibreTube#8803 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
Telegram !!! オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
Xposed-Modules-Repo/com.fuck.iab#24 · コメント 3 件 · リアクション 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
SimonHalvdansson/Harmonic-HN#361 ·