Skip to content

fix(scopes): Walk parent chain iteratively in isAncestorOf - #6249

Open
hocaron wants to merge 2 commits into
getsentry:mainfrom
hocaron:fix/isancestorof-iterative
Open

hocaron wants to merge 2 commits into
getsentry:mainfrom
hocaron:fix/isancestorof-iterative

Conversation

@hocaron

@hocaron hocaron commented Oct 12, 2026

Copy link
Copy Markdown

📜 Description

Scopes.isAncestorOf recursed once per parent link. It now walks the parentScopes chain with a loop, so a long chain can't throw StackOverflowError. Behaviour is otherwise unchanged.

💡 Motivation and Context

Split out from #6248, as mentioned there. This PR does not fix the leak itself, only the stack overflow a long chain can cause.

Long Scopes chains happen in practice: a task that re-schedules itself through SentryScheduleHook gets a new fork whose parent is the previous run's fork (see #6248, similar to #5051). We saw chains of ~38k links after ~13 days in production.

Since #6004, Sentry.getCurrentScopes() calls root.isAncestorOf(scopes) in globalHubMode, so the recursion can run on a hot path. The OTel SentryContextWrapper also calls isAncestorOf.

💚 How did you test it?

Added ScopesTest › isAncestorOf does not overflow the stack on a deep chain: builds 20,000 chained forkedCurrentScope forks and calls root.isAncestorOf(deepest) on a thread with a 256 KB stack.

  • On main: fails with expected:<true> but was:<java.lang.StackOverflowError>
  • With this change: passes

./gradlew :sentry:test :sentry:apiCheck :sentry:spotlessCheck passes locally (JDK 17).

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

The fix that stops the chain from growing in the first place is proposed in #6248.

isAncestorOf recursed once per parent link, so a long Scopes chain
(e.g. from a task that keeps re-scheduling itself through
SentryScheduleHook) could throw StackOverflowError. Since getsentry#6004 this is
also called from Sentry.getCurrentScopes() in globalHubMode.

Walk the chain with a loop instead. Results are unchanged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant