Skip to content

fix: stop Sentry's managed ANR watchdog running alongside DclAnrIntegration - #9942

Merged
mikhail-dcl merged 1 commit into
devfrom
fix/sentry-managed-anr-duplicate
Sep 2, 2026
Merged

fix: stop Sentry's managed ANR watchdog running alongside DclAnrIntegration#9942
mikhail-dcl merged 1 commit into
devfrom
fix/sentry-managed-anr-duplicate

Conversation

@mikhail-dcl

Copy link
Copy Markdown
Collaborator

What does this PR change?

Fixes a regression that reached dev with the Unity 6.5 upgrade (#9871, squashed as 78705998b4).

That PR bumped io.sentry.unity 4.0.0 → 4.9.0, which deprecated DisableAnrIntegration(). The call was replaced with options.EnableAppHangTracking = false on the strength of the deprecation message. The two are not equivalent.

what it does
DisableAnrIntegration() literally options.RemoveIntegration<AnrIntegration>() — removed Sentry's managed C# watchdog
EnableAppHangTracking only feeds NativeAppHangTrackingEnabled — the native app-hang detector in sentry-native / sentry-cocoa

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.

The fix

Clear AnrDetectionEnabled in SentryOptions.asset so 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 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. The comment now says what the property actually gates.

Test Instructions

Expected result: exactly one ANR report per hang, from DclAnrIntegration (mechanism MainThreadWatchdog), with a minidump attached. Before this change a hang could produce two events.

Test Steps

  1. Run a build with Sentry enabled and a DSN configured.
  2. Induce a main-thread hang longer than the 5 s threshold.
  3. In Sentry, confirm a single ANR issue arrives, tagged with the MainThreadWatchdog mechanism, and that no second issue arrives from Sentry's own ANR integration.
  4. Confirm normal error reporting and breadcrumbs still work.

Additional Testing Notes

Verified by reading getsentry/sentry-unity at tag 4.9.0: SentryUnityOptionsExtensions.cs:108, SentryUnityOptions.cs:243-260, ScriptableSentryUnityOptions.cs:127 and :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

  • Changes have been tested locally
  • Documentation has been updated (if required)
  • Performance impact has been considered
  • For SDK features: Test scene is included

…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>
@mikhail-dcl
mikhail-dcl requested review from a team as code owners September 2, 2026 12:37
@github-actions
github-actions Bot requested a review from DafGreco September 2, 2026 12:37
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🚦 CI Status

Build

Platform Links & timing
Windows GitHub job · Unity Cloud #1
Mac GitHub job · Unity Cloud #1

Lint

Lint in progress, come back later!

Tests

Waiting for tests to start…

Performance

Bare-metal benchmarks run automatically after each successful build; results land in this section. Add the perf_test label to run the in-repo Unity performance suite instead (skips normal CI and blocks merge while set).

Automation

On demand — comment /visual-tests on this PR to run the visual regression suite against its build.

@decentraland-bot
decentraland-bot self-requested a review September 2, 2026 12:37

@decentraland-bot decentraland-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ScriptableSentryUnityOptions reads AnrDetectionEnabled and adds the integration before Configure() runs, the serialized asset is the only place to prevent it.
  • PersistIntoAssetFile will not revert the flag: verified — it only writes Enabled, ReleaseOverride, Dsn, and EnvironmentOverride. AnrDetectionEnabled is untouched.
  • EnableAppHangTracking = false retained deliberately: disables the native detector as well, since DclAnrIntegration handles 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 DclAnrIntegration does 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

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved based on Jarvis review — simple fix/chore with no blocking issues. QA approval is still required.

@mikhail-dcl
mikhail-dcl merged commit 7bbb247 into dev Sep 2, 2026
20 of 31 checks passed
@mikhail-dcl
mikhail-dcl deleted the fix/sentry-managed-anr-duplicate branch September 2, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants