fix: Recreate SentryOptions on each init cycle#503
Merged
Conversation
Move options ownership from a static singleton to SentrySDK. Each call to init() now creates fresh options via a factory method, preventing runtime values (before_send, event_processors, etc.) from leaking across close()/init() cycles. - Replace SentryOptions singleton with create_from_project_settings() factory that returns a new Ref<SentryOptions> loaded from project settings - SentrySDK owns options via Ref<SentryOptions> member with get_options() accessor and SENTRY_OPTIONS() convenience macro - SentryExperimental holds a raw pointer to its owning SentryOptions instead of routing through a global accessor - Move built-in event processor registration into init() so processors don't accumulate on repeated init cycles - SentryOptions constructor only sets code defaults, keeping doc generation clean from project settings values Fixes #501 Co-Authored-By: Claude <[email protected]>
SentryExperimental holds a raw pointer back to its owning SentryOptions. Since SentryExperimental is RefCounted, it can outlive the parent if GDScript holds a reference. Clear the pointer in the destructor so surviving references safely hit null checks instead of accessing freed memory. Co-Authored-By: Claude <[email protected]>
Contributor
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. Bug Fixes 🐛
Internal Changes 🔧
Other
🤖 This preview updates automatically when you update the PR. |
Refs #501 Co-Authored-By: Claude <[email protected]>
66bbecc to
0babaef
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
The SentrySDK constructor runs before `create_singleton()` assigns the static singleton pointer. Logging calls during platform SDK creation dereference the null singleton via SENTRY_OPTIONS(), causing a crash. Move platform-specific SDK backend creation from the constructor to `prepare_and_auto_initialize()`, which runs after the singleton is set. The constructor now defaults to DisabledSDK and creates options eagerly. Co-Authored-By: Claude <[email protected]>
Reset the internal_sdk shared_ptr before setting singleton to nullptr, so that sentry_close() callbacks can still access SENTRY_OPTIONS() during shutdown. Previously, the shared_ptr was destroyed during member destruction after singleton was already null, causing SIGSEGV on exit. Co-Authored-By: Claude <[email protected]>
SentrySDK is the sole owner of the InternalSDK instance. Change from shared_ptr to unique_ptr to better express this ownership semantic. The accessor now returns a raw pointer since callers only use it transiently. Co-Authored-By: Claude <[email protected]>
jpnurmi
approved these changes
Feb 11, 2026
This was referenced Feb 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
After switching from automatic-init-only to supporting explicit
init()/close()cycles,SentryOptionsretained its legacy singleton model. The singleton was created once at extension load and never recreated, so callingSentrySDK.close()followed bySentrySDK.init()caused old state to leak into the next session — callbacks, modified options, and event processors all persisted.Move
SentryOptionsownership from a static singleton toSentrySDK, so eachinit()call creates fresh options loaded from project settings. This prevents runtime values (before_send, event processors, etc.) from leaking acrossclose()/init()cycles.Key changes:
SentryOptionssingleton withcreate_from_project_settings()factorySentrySDKowns options viaRef<SentryOptions>member, exposed throughget_options()accessor andSENTRY_OPTIONS()macroSentryExperimentaluses a raw owner pointer (with null-safety in destructor) instead of routing through a global accessorinit()so processors don't accumulate on repeated cycles