fix: stop Sentry's managed ANR watchdog running alongside DclAnrIntegration - #9942
Conversation
…ration The Unity 6.5 upgrade (#9871) bumped io.sentry.unity 4.0.0 -> 4.9.0, which deprecated DisableAnrIntegration(). That call was replaced with EnableAppHangTracking = false on the strength of the deprecation message, but the two are not equivalent: - DisableAnrIntegration() was literally options.RemoveIntegration<AnrIntegration>() - it removed Sentry's managed C# watchdog. - EnableAppHangTracking only feeds NativeAppHangTrackingEnabled, i.e. the NATIVE app-hang detector in sentry-native / sentry-cocoa. It does nothing to the managed integration. ScriptableSentryUnityOptions adds AnrIntegration when AnrDetectionEnabled is set, and it does so before OptionsConfiguration runs - so Configure() never had a chance to prevent it, only to remove it after the fact. With the removal gone, Sentry's watchdog has been running alongside DclAnrIntegration: two watchdog threads and duplicate ANR events. EnableAppHangTracking is also not serialized in SentryOptions.asset, so it was already false by compiled default - the replacement line was a no-op as well as the wrong lever. Fix at the source instead: clear AnrDetectionEnabled so the integration is never added. This avoids re-introducing the obsolete API (the property is [Obsolete] in code, but setting the serialized field raises no CS0618), and PersistIntoAssetFile only writes Enabled/Release/Dsn/Environment, so it will not silently revert the flag. EnableAppHangTracking = false is kept deliberately - we do not want Sentry's native app-hang detector either, since DclAnrIntegration already reports ANRs with minidumps and callstacks - and the comment now says what the property actually gates. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
🚦 CI Status
Lint in progress, come back later! Waiting for tests to start… Bare-metal benchmarks run automatically after each successful build; results land in this section. Add the On demand — comment |
decentraland-bot
left a comment
There was a problem hiding this comment.
Review — PR #9942
fix: stop Sentry's managed ANR watchdog running alongside DclAnrIntegration
STEP 2 — Root-cause check: PASS ✅
The PR correctly identifies the root cause: the Sentry Unity SDK upgrade (4.0.0 → 4.9.0) replaced DisableAnrIntegration() with EnableAppHangTracking = false, but these are not equivalent.
| API | What it controls |
|---|---|
DisableAnrIntegration() |
Removed Sentry's managed C# AnrIntegration via RemoveIntegration<AnrIntegration>() |
EnableAppHangTracking |
Only gates the native app-hang detector (sentry-native / sentry-cocoa) |
ScriptableSentryUnityOptions adds AnrIntegration when AnrDetectionEnabled is set, before Configure() runs — so the managed watchdog was silently left running alongside DclAnrIntegration, producing duplicate ANR events.
The fix disables AnrDetectionEnabled at the serialized asset level, preventing the integration from ever being instantiated. This addresses the cause, not a symptom.
STEP 3 — Design & integration: PASS ✅
No new code units introduced — this is purely a configuration correction plus a clarifying comment.
- Asset-level approach is correct: since
ScriptableSentryUnityOptionsreadsAnrDetectionEnabledand adds the integration beforeConfigure()runs, the serialized asset is the only place to prevent it. PersistIntoAssetFilewill not revert the flag: verified — it only writesEnabled,ReleaseOverride,Dsn, andEnvironmentOverride.AnrDetectionEnabledis untouched.EnableAppHangTracking = falseretained deliberately: disables the native detector as well, sinceDclAnrIntegrationhandles all ANR reporting with minidumps and callstacks. The updated comment accurately documents this.- No subscriptions, resources, or lifecycle changes: nothing to trace.
STEP 4 — Member audit: N/A
No public properties or accessors added or changed.
STEP 5 — Line-level review: No issues found
Pass A (Blocking issues): No bugs, security vulnerabilities, performance issues, missing error handling, resource leaks, or nullability violations.
Pass B (Design/encapsulation smells): The updated comment explains a non-obvious SDK constraint (the timing relationship between ScriptableSentryUnityOptions and Configure()). This is necessary documentation — without it, a future developer might attempt to consolidate both disabling mechanisms into Configure() alone, reintroducing the bug.
Security review: PASS ✅
- No secrets, credentials, or DSN values exposed in the diff
- No new inputs, network calls, or auth changes
- Disabling Sentry's built-in ANR detection in favor of the custom
DclAnrIntegrationdoes not degrade error reporting — it eliminates a duplicate reporter while preserving the richer one (minidumps + callstacks)
STEP 6 — Complexity
SIMPLE — 2 files, ~5 lines changed, config flag toggle and comment update only.
STEP 7 — QA assessment
QA_REQUIRED: YES — the change affects runtime Sentry configuration (ANR detection behavior). Verification requires inducing a hang in a Sentry-enabled build and confirming a single ANR event from DclAnrIntegration.
STEP 8 — Non-blocking warnings
None.
REVIEW_RESULT: PASS ✅
COMPLEXITY: SIMPLE
COMPLEXITY_REASON: Config-only change toggling a serialized Sentry asset flag and updating an explanatory comment — no ECS, async, or runtime logic changes.
QA_REQUIRED: YES
Reviewed by Jarvis 🤖 · Requested by decentraland-bot via GitHub
What does this PR change?
Fixes a regression that reached
devwith the Unity 6.5 upgrade (#9871, squashed as78705998b4).That PR bumped
io.sentry.unity4.0.0 → 4.9.0, which deprecatedDisableAnrIntegration(). The call was replaced withoptions.EnableAppHangTracking = falseon the strength of the deprecation message. The two are not equivalent.DisableAnrIntegration()options.RemoveIntegration<AnrIntegration>()— removed Sentry's managed C# watchdogEnableAppHangTrackingNativeAppHangTrackingEnabled— the native app-hang detector insentry-native/sentry-cocoaScriptableSentryUnityOptionsaddsAnrIntegrationwhenAnrDetectionEnabledis set, and it does so beforeOptionsConfigurationruns — soConfigure()never had a chance to prevent it, only to remove it after the fact. With the removal gone, Sentry's watchdog has been running alongsideDclAnrIntegration: two watchdog threads and duplicate ANR events.EnableAppHangTrackingis also not serialized inSentryOptions.asset, so it was alreadyfalseby compiled default — the replacement line was a no-op as well as the wrong lever.The fix
Clear
AnrDetectionEnabledinSentryOptions.assetso the integration is never added in the first place. That avoids re-introducing the obsolete API — the property is[Obsolete]in code, but setting the serialized field raises noCS0618— andPersistIntoAssetFileonly writesEnabled/Release/Dsn/Environment, so it will not silently revert the flag.EnableAppHangTracking = falseis kept deliberately: we do not want Sentry's native app-hang detector either, sinceDclAnrIntegrationalready reports ANRs with minidumps and callstacks. The comment now says what the property actually gates.Test Instructions
Expected result: exactly one ANR report per hang, from
DclAnrIntegration(mechanismMainThreadWatchdog), with a minidump attached. Before this change a hang could produce two events.Test Steps
MainThreadWatchdogmechanism, and that no second issue arrives from Sentry's own ANR integration.Additional Testing Notes
Verified by reading
getsentry/sentry-unityat tag4.9.0:SentryUnityOptionsExtensions.cs:108,SentryUnityOptions.cs:243-260,ScriptableSentryUnityOptions.cs:127and:304-310. Not verified at runtime — no ANR was reproduced against a build, so the "duplicate events" consequence is derived from the source path rather than observed.Quality Checklist