Skip to content

Data race between _PyMonitoring_RegisterCallback and _Py_call_instrumentation_2args in instrumentation.c #131141

Closed
@vfdev-5

Description

@vfdev-5

Bug report

Bug description:

I built cpython 3.13 from source with TSAN and running the following code:

import sys
import concurrent.futures
import threading


if __name__ == "__main__":
    num_workers = 20
    num_runs = 100

    barrier = threading.Barrier(num_workers)

    tool_id = 3
    event_id = sys.monitoring.events.CALL

    sys.monitoring.use_tool_id(tool_id, "test_tool_1")
    sys.monitoring.set_events(tool_id, event_id)


    def closure():
        barrier.wait()

        def my_callback(code, instruction_offset, callable, arg0):
            pass

        sys.monitoring.register_callback(tool_id, event_id, my_callback)

        def example_function():
            a = 1
            b = 2
            c = a + b

        for _ in range(num_runs):
            example_function()

    with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
        futures = []
        for i in range(num_workers):
            futures.append(executor.submit(closure))
        assert len(list(f.result() for f in futures)) == num_workers

TSAN reports the following data race: https://gist.github.com/vfdev-5/e80f9b4528993eb1543e45a9216350e3#file-repro-log

cpython version:

Python 3.13.2+ experimental free-threading build (heads/3.13:9e0fce413a9, Mar 12 2025, 00:48:15) [Clang 18.1.3 (1ubuntu1)]

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13bugs and security fixes3.14bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions