GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-154348: fix data race on nogil build about `sys.monitoring.use_tool_id()` by weixlu · Pull Request #154459 · python/cpython

Conversation

@weixlu

@weixlu weixlu commented Jul 22, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

As reported in #154348 (found by devdanzin's fusil), interp->monitoring_tool_names[tool_id] for sys.monitoring is accessed without any synchronization, which is a data race on free-threaded build.

The fix is straightforward, just add a dedicated PyMutex and serialize all access on monitoring_tool_names

Testing

  • The reproducer (8 threads × 6000 rounds) now runs clean under a TSAN build.
  • This PR only adds a mutex, so basic functional behavior is unchanged.

Notes for reviewer:

  • Of course the writer need a lock, but why reader (i.e. monitoring.get_tool) needs one as well? Because it reads the pointer and then increfs it. A concurrent free_tool_id can run Py_CLEAR (drop the last reference and free the object) in between, turning the Py_NewRef into a use-after-free.
  • The clear/free paths calls _PyMonitoring_ClearToolId, which internally does a stop-the-world. Is it safe to hold a PyMutex across STW? This is safe, because a thread blocked on PyMutex_Lock detaches its thread state, so it is seen as stopped.
  • Issue: Free threading: Data race on tool_id in sys.monitoring #154348

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot mentioned this pull request Jul 22, 2026
Free threading: Data race on tool_id in sys.monitoring #154348
Open
@bedevere-app bedevere-app Bot added the awaiting review label Jul 22, 2026
@weixlu weixlu mentioned this pull request Jul 22, 2026
Free-threading data races in CPython: 15 findings (9 new + 6 residual of existing FT work) #153852
Open
@weixlu
pythongh-154348: fix data race on nogil build about `sys.monitoring.u…
761667a
…se_tool_id()`
@weixlu
weixlu force-pushed the race branch from 9bc1100 to 761667a Compare July 30, 2026 11:06
@weixlu

weixlu commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

I discussed this with @gaogaotiantian , and he'd like to see if there are approaches other than a lock to handle the data race. I've put together a few options:

  1. The current approach — use a dedicated PyMutex.

  2. Use Py_BEGIN_CRITICAL_SECTION to declare a critical section. The underlying mechanism is still a lock, and there's already similar usage in instrumentation.c, see:

  #define LOCK_CODE(code)                                             \
      assert(!_PyInterpreterState_GET()->stoptheworld.world_stopped); \
      Py_BEGIN_CRITICAL_SECTION(code)
  1. Use atomic operations (CAS, etc.), which would avoid the lock overhead and give better performance. That said, I think monitoring_tool is a fairly cold path, so the benefit of
    going lock-free isn't significant, and atomic op is more error-prone. Of course, if there's a need for it, I'm happy to implement and post it for review.
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

This PR is stale because it has been open for 90 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting review stale Stale PR or inactive for long period of time.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@weixlu
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.