Skip to content

fix(core): Prevent HubSwitchGuard panic at thread teardown#1241

Merged
szokeasaurusrex merged 1 commit into
masterfrom
szokeasaurusrex/panic-in-panic-fix
Jul 14, 2026
Merged

fix(core): Prevent HubSwitchGuard panic at thread teardown#1241
szokeasaurusrex merged 1 commit into
masterfrom
szokeasaurusrex/panic-in-panic-fix

Conversation

@szokeasaurusrex

Copy link
Copy Markdown
Member

When a HubSwitchGuard is dropped, the THREAD_HUB is meant to be restored to its previous value.

In the past, we performed this swap using THREAD_HUB.with, which panics if the THREAD_HUB thread-local has been destroyed, which can be the case during thread destruction. Essentially, if a HubSwitchGuard is stored in a thread-local until the thread terminates, it can happen that the THREAD_HUB is destroyed before the HubSwitchGuard is dropped, leading to a panic when the HubSwitchGuard is dropped. TLS drop order is not guaranteed by Rust, but, at least on macOS platforms, this behavior reliably occurs if the thread-local storing the HubSwitchGuard gets initialized before the THREAD_HUB thread-local variable.

The solution here is simple: instead of using THREAD_HUB.with, we use THREAD_HUB.try_with, which returns an error rather than panicking in the case that the THREAD_HUB has been destroyed. We ignore any resulting errors because, if the THREAD_HUB thread-local slot has been destroyed, there is nothing to swap back to the original value, and this would anyways typically occur only when the thread is shutting down.

We also add two regression tests, at least one of which should fail if the bug is reintroduced. As the TLS drop order is not guaranteed by the language, we test both initializing the guard slot before the THREAD_HUB (this reliably fails on macOS when the bug is introduced), and we also test initializing THREAD_HUB before the HubSwitchGuard slot (this reliably passes on macOS, even without the fix, but may fail on other platforms depending on implementation).

Fixes #1237
Fixes RUST-264

@szokeasaurusrex
szokeasaurusrex requested a review from a team as a code owner July 14, 2026 08:24
@linear-code

linear-code Bot commented Jul 14, 2026

Copy link
Copy Markdown

RUST-264

When a `HubSwitchGuard` is dropped, the `THREAD_HUB` is meant to be restored to its previous value.

In the past, we performed this swap using `THREAD_HUB.with`, which panics if the `THREAD_HUB` thread-local has been destroyed, which can be the case during thread destruction. Essentially, if a `HubSwitchGuard` is stored in a thread-local until the thread terminates, it can happen that the `THREAD_HUB` is destroyed before the `HubSwitchGuard` is dropped, leading to a panic when the `HubSwitchGuard` is dropped. TLS drop order is not guaranteed by Rust, but, at least on macOS platforms, this behavior reliably occurs if the thread-local storing the `HubSwitchGuard` gets initialized before the `THREAD_HUB` thread-local variable.

The solution here is simple: instead of using `THREAD_HUB.with`, we use `THREAD_HUB.try_with`, which returns an error rather than panicking in the case that the `THREAD_HUB` has been destroyed. We ignore any resulting errors because, if the `THREAD_HUB` thread-local slot has been destroyed, there is nothing to swap back to the original value, and this would anyways typically occur only when the thread is shutting down.

We also add two regression tests, at least one of which should fail if the bug is reintroduced. As the TLS drop order is not guaranteed by the language, we test both initializing the guard slot before the `THREAD_HUB` (this reliably fails on macOS when the bug is introduced), and we also test initializing `THREAD_HUB` before the `HubSwitchGuard` slot (this reliably passes on macOS, even without the fix, but may fail on other platforms depending on implementation).

Fixes [#1237](#1237)
Fixes [RUST-264](https://linear.app/getsentry/issue/RUST-264)
@szokeasaurusrex
szokeasaurusrex force-pushed the szokeasaurusrex/panic-in-panic-fix branch from 2dfbe2e to efabaf8 Compare July 14, 2026 08:30
@szokeasaurusrex
szokeasaurusrex merged commit aab9f34 into master Jul 14, 2026
30 checks passed
@szokeasaurusrex
szokeasaurusrex deleted the szokeasaurusrex/panic-in-panic-fix branch July 14, 2026 09:12
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.

SwitchGuard::drop panics during TLS destruction (then double-panics in the panic hook), aborting the process

2 participants