Skip to content

Core re-entrancy guard for user callbacks (beforeSend/beforeBreadcrumb/beforeSendLog) #5738

Description

@runningcode

Problem

A user beforeSend / beforeBreadcrumb / beforeSendLog callback that triggers another SDK capture — directly, or transitively through a logging integration that routes back into Sentry (Timber's SentryTimberTree, or the Gradle plugin's logcat instrumentation) — recurses until a StackOverflowError. The callbacks run synchronously on the caller thread with only a try/catch; nothing prevents re-entrant capture.

This is the same class of bug as the logcat crash SDK-CRASHES-JAVA-3T3H (fixed per-integration in #5734). Investigation confirmed Timber has it too, and the core offers no protection, so we fix the whole class once in the core.

Fix

SentryCallbackReentrancyGuard: a shared thread-local flag set only around each callback's execute(...). Capture entry points (SentryClient.captureEvent/captureTransaction/captureLog, Scope.addBreadcrumb) drop a nested capture while the flag is active, breaking the loop for every capture type. Event-processor captures run outside the flag and are unaffected.

Behavioral change: a capture a callback makes intentionally is dropped while that callback runs (logged at DEBUG). Dropping rather than sending is deliberate — bypassing beforeSend would risk unscrubbed PII. Makes the per-integration SentryLogcatAdapter guard redundant.

Covered by regression tests in SentryClientTest, ScopeTest, and an end-to-end SentryTimberIntegrationTest.

Links

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions