Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-127020: Make PyCode_GetCode thread-safe for free threading #127043

Merged
merged 1 commit into from
Nov 21, 2024

Conversation

colesbury
Copy link
Contributor

@colesbury colesbury commented Nov 19, 2024

Some fields in PyCodeObject are lazily initialized. Use atomics and critical sections to make their initializations and accesses thread-safe.

Some fields in PyCodeObject are lazily initialized. Use atomics and
critical sections to make their initializations and accesses thread-safe.
@vfdev-5
Copy link

vfdev-5 commented Nov 21, 2024

Hi @colesbury , Lysandros pointed me out to your PR fixing a bug in FT mode.
I had another repro code showing randomly tsan warnings in get_cached_locals and init_co_cached :

import concurrent.futures
import threading
import inspect


def decorator(f):
    # Introspect the callable for optional features.
    sig = inspect.signature(f)
    for param in sig.parameters.values():
        pass

    def emit_call_op(*call_args):
        pass

    wrapped = emit_call_op
    return wrapped


def test_dialects_vector_repro_3():
    num_workers = 6
    num_runs = 10
    barrier = threading.Barrier(num_workers)

    def closure():
        barrier.wait()
        for _ in range(num_runs):

            @decorator
            def print_vector(arg):
                return 0

        barrier.wait()

    with concurrent.futures.ThreadPoolExecutor(
        max_workers=num_workers
    ) as executor:
        futures = []
        for _ in range(num_workers):
            futures.append(executor.submit(closure))
        # We should call future.result() to re-raise an exception if test has
        # failed
        assert len(list(f.result() for f in futures)) == num_workers


if __name__ == "__main__":
    test_dialects_vector_repro_3()

Outputs (cpython 3.13 built with TSAN):

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7fedfa39de10 by thread T6:
    #0 init_co_cached /tmp/cpython-tsan/Objects/codeobject.c:309:26 (python3.13t+0x1e6441) (BuildId: f1122943b999261e166922e88bbc71af5ecf54a9)
    #1 _PyCode_GetVarnames /tmp/cpython-tsan/Objects/codeobject.c:1562:9 (python3.13t+0x1e6441)
    #2 code_getvarnames /tmp/cpython-tsan/Objects/codeobject.c:2107:12 (python3.13t+0x1e6441)
    #3 getset_get /tmp/cpython-tsan/Objects/descrobject.c:193:16 (python3.13t+0x1eb966) (BuildId: f1122943b999261e166922e88bbc71af5ecf54a9)

or

  Read of size 8 at 0x7efddc0e0068 by thread T2:
    #0 get_cached_locals /tmp/cpython-tsan/Objects/codeobject.c:1547:9 (python3.13t+0x1e0e8a) (BuildId: f1122943b999261e166922e88bbc71af5ecf54a9)
    #1 _PyCode_GetVarnames /tmp/cpython-tsan/Objects/codeobject.c:1565:12 (python3.13t+0x1e6484) (BuildId: f1122943b999261e166922e88bbc71af5ecf54a9)
    #2 code_getvarnames /tmp/cpython-tsan/Objects/codeobject.c:2107:12 (python3.13t+0x1e6484)
    #3 getset_get /tmp/cpython-tsan/Objects/descrobject.c:193:16 (python3.13t+0x1eb966) (BuildId: f1122943b999261e166922e88bbc71af5ecf54a9)

Can you please check and run it in your PR and see if this is also fixed? Thanks a lot!

@colesbury
Copy link
Contributor Author

@vfdev-5, I verified that it fixed your repro as well.

@colesbury colesbury merged commit 3926842 into python:main Nov 21, 2024
49 checks passed
@miss-islington-app
Copy link

Thanks @colesbury for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖

@colesbury colesbury deleted the gh-127020-code-get-code branch November 21, 2024 16:00
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Nov 21, 2024
…pythonGH-127043)

Some fields in PyCodeObject are lazily initialized. Use atomics and
critical sections to make their initializations and accesses thread-safe.
(cherry picked from commit 3926842)

Co-authored-by: Sam Gross <colesbury@gmail.com>
@bedevere-app
Copy link

bedevere-app bot commented Nov 21, 2024

GH-127107 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.13 bugs and security fixes label Nov 21, 2024
colesbury added a commit that referenced this pull request Nov 21, 2024
GH-127043) (GH-127107)

Some fields in PyCodeObject are lazily initialized. Use atomics and
critical sections to make their initializations and accesses thread-safe.
(cherry picked from commit 3926842)

Co-authored-by: Sam Gross <colesbury@gmail.com>
ebonnal pushed a commit to ebonnal/cpython that referenced this pull request Jan 12, 2025
…python#127043)

Some fields in PyCodeObject are lazily initialized. Use atomics and
critical sections to make their initializations and accesses thread-safe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants