Skip to content

fix(profiler): reset ThreadContinuousScheduler lock after fork - #7275

Open
BetterAndBetterII wants to merge 1 commit into
getsentry:masterfrom
BetterAndBetterII:fix/thread-continuous-scheduler-fork-safety
Open

BetterAndBetterII wants to merge 1 commit into
getsentry:masterfrom
BetterAndBetterII:fix/thread-continuous-scheduler-fork-safety

Conversation

@BetterAndBetterII

Copy link
Copy Markdown

Summary

ThreadContinuousScheduler.lock can be inherited locked across os.fork(). The holding thread does not exist in the child, so ensure_running can deadlock forever when it tries to acquire the lock.

This mirrors the Monitor fix from #6159: register an os.register_at_fork(after_in_child=...) hook (via weakref.WeakMethod) that reinitialises the lock and clears the inherited thread / pid / running / buffer so the child starts clean.

Scope is deliberately limited to ThreadContinuousScheduler (#6165). SessionFlusher / BackgroundWorker (#6164) are left alone.

Test plan

  • python -m pytest tests/profiler/test_continuous_profiler.py::test_thread_continuous_scheduler_lock_reset_in_child_after_fork -v
  • RED without the hook (child exits 1), GREEN with it (child exits 0)

Fixes #6165

If os.fork() runs while ThreadContinuousScheduler.lock is held, the child
inherits a locked lock with no owner and ensure_running can deadlock.
Mirror the Monitor getsentry#6159 pattern: register_at_fork after_in_child reset.

Fixes getsentry#6165
@BetterAndBetterII
BetterAndBetterII requested a review from a team as a code owner August 27, 2026 19:52
sentrivana pushed a commit that referenced this pull request Nov 9, 2026
### Description

Removes `ContinuousScheduler.pause()` from
`sentry_sdk/profiler/continuous_profiler.py` (3 lines). It's a stub that
only raises `NotImplementedError`, and nothing implements it or calls
it.

#2830 (Jun 2024, "Introduce continuous profiling mode") added it next to
`ensure_running()` and `teardown()`. Unlike those two, no subclass ever
overrode it, and the SDK never called it. The stub makes it look like
the continuous profiler can be paused, but it can't.

**Evidence**
- `git grep -nw pause` on `master` finds only the definition. Nothing in
`sentry_sdk/`, `tests/`, `scripts/` or `docs/` refers to it.
- `ThreadContinuousScheduler` and `GeventContinuousScheduler`, the only
subclasses, override `ensure_running()` and `teardown()` but not
`pause()`.
- `git log -S "def pause"` finds only #2830. `git log -S ".pause("`
across `sentry_sdk` and `tests` finds no commits, so it has never had a
caller.
- `ContinuousScheduler` isn't exported from `sentry_sdk.profiler`
(`__all__` lists only the transaction-profiler schedulers) and isn't
documented.
- No open PR or issue mentions it. #7275 also touches
`continuous_profiler.py`, but in different hunks
(`ThreadContinuousScheduler.__init__`).

**Why it's safe**
- `ContinuousScheduler` is an internal class. The method is unreachable,
so behavior doesn't change, and no public API or documented behavior is
affected.

**Checks**
- `uv run ruff check` / `ruff format --check` on `sentry_sdk/profiler`:
clean
- `uv run --group typing mypy sentry_sdk`: no issues
- `TESTPATH=tests/profiler uv run tox -e py3.14-common`: 106 passed, 69
skipped. The skipped tests are the gevent cases, which need gevent
installed.

#### Issues
None. Found by the weekly sentry-python removal scout.

<!-- junior-request-attribution:start -->
via [automation
`sched_65eed06cc199036c2b13411096f412d4`](https://junior-prod.sentry.dev/automations/sched_65eed06cc199036c2b13411096f412d4)
· Run ID `sched_65eed06cc199036c2b13411096f412d4:1794211200000`.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!--
junior-conversation-id:agent-dispatch%3Adispatch_0096be51ec4ca0f294d1b5786520632b
-->

--

[View
Session](https://junior-prod.sentry.dev/conversations/agent-dispatch%3Adispatch_0096be51ec4ca0f294d1b5786520632b)
[[Sentry]](https://sentry.sentry.io/explore/conversations/agent-dispatch%3Adispatch_0096be51ec4ca0f294d1b5786520632b/?project=4510944073809921)

<!-- junior-session-footer:end -->

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>

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.

Introduce fork-safety to ThreadContinuousScheduler

1 participant