Skip to content

Race in concurrent list mutation and item retrieval #129069

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

Open
Yhg1s opened this issue Jan 20, 2025 · 2 comments
Open

Race in concurrent list mutation and item retrieval #129069

Yhg1s opened this issue Jan 20, 2025 · 2 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-free-threading type-bug An unexpected behavior, bug, or error

Comments

@Yhg1s
Copy link
Member

Yhg1s commented Jan 20, 2025

Bug report

Bug description:

A data race exists in lists when they are concurrently updated and indexed (or otherwise accessed): for slice assignment and other ways of adding or removing multiple items (list.extend, in-place multiplication), memory writes to the newly allocated areas happen with memcpy/memmove, which have no write size/atomicity guarantees (and it's not unlikely that they will perform jagged writes). These reallocations happen with the lock held, but since we're relying on QSBR, concurrent reads of those memory areas are technically possible.

The tests in PR #128798 (test_free_threading.test_iteration), when run under ThreadSanitizer, expose those races. (They are suppressed in Tools/tsan/suppressions_free_threading.txt).

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

@Yhg1s Yhg1s added topic-free-threading type-bug An unexpected behavior, bug, or error labels Jan 20, 2025
@colesbury
Copy link
Contributor

I'm a bit confused by the "memory writes to the newly allocated areas happen with memcpy/memmove" part of the issue description.

The data races with memcpy I've seen involve writes to the existing item array. For example, in list_ass_slice_lock_held, we have memmove calls with self->ob_item and recycle as the destinations. The ones with the newly allocated recycle as the destination are okay, but the ones with self->ob_item are potentially a problem.

@Yhg1s
Copy link
Member Author

Yhg1s commented Jan 20, 2025

Yes, you're right, 'newly allocated' isn't really relevant. I just meant that the calls that move items around before/after list_resize() are potentially problematic. I have to admit my head hurts every time I try to trace through list_ass_slice_lock_held.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-free-threading type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants