Skip to content

Type slots are not thread-safe in free-threaded builds #127266

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
mpage opened this issue Nov 25, 2024 · 2 comments
Open

Type slots are not thread-safe in free-threaded builds #127266

mpage opened this issue Nov 25, 2024 · 2 comments
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-free-threading type-bug An unexpected behavior, bug, or error

Comments

@mpage
Copy link
Contributor

mpage commented Nov 25, 2024

Bug report

Bug description:

Modification of type slots is protected by the global type lock, however, type slots are read non-atomically without holding the type lock. For example, in PyObject_SetItem:

cpython/Objects/abstract.c

Lines 231 to 235 in 5bb059f

if (m && m->mp_ass_subscript) {
int res = m->mp_ass_subscript(o, key, value);
assert(_Py_CheckSlotResult(o, "__setitem__", res >= 0));
return res;
}

It's not clear how we want to address this. From @colesbury in #127169 (comment):

I'd lean towards doing a stop-the-world pause when modifying the slot so that we don't need 
to change every read. I expect that to be a bit tricky since class definitions look like they're mutating 
the class.

CPython versions tested on:

3.13, 3.14, CPython main branch

Operating systems tested on:

Linux

Linked PRs

@mpage mpage added type-bug An unexpected behavior, bug, or error 3.13 bugs and security fixes topic-free-threading 3.14 new features, bugs and security fixes labels Nov 25, 2024
@Pitmbar

This comment was marked as off-topic.

@colesbury
Copy link
Contributor

For future reference, you can reproduce this race by running the following test with TSAN enabled:

./python -m test test_opcache -m test_load_attr_method_lazy_dict

colesbury added a commit to colesbury/cpython that referenced this issue Feb 7, 2025
Fix a few thread-safety bugs to enable test_opcache when run with TSAN:

 * Use relaxed atomics when clearing `ht->_spec_cache.getitem`
   (pythongh-115999)
 * Add temporary suppression for type slot modifications (pythongh-127266)
 * Use atomic load when reading `*dictptr`
colesbury added a commit to colesbury/cpython that referenced this issue Feb 10, 2025
Fix a few thread-safety bugs to enable test_opcache when run with TSAN:

 * Use relaxed atomics when clearing `ht->_spec_cache.getitem`
   (pythongh-115999)
 * Add temporary suppression for type slot modifications (pythongh-127266)
 * Use atomic load when reading `*dictptr`
colesbury added a commit that referenced this issue Feb 11, 2025
Fix a few thread-safety bugs to enable test_opcache when run with TSAN:

 * Use relaxed atomics when clearing `ht->_spec_cache.getitem`
   (gh-115999)
 * Add temporary suppression for type slot modifications (gh-127266)
 * Use atomic load when reading `*dictptr`
colesbury added a commit to colesbury/cpython that referenced this issue Feb 26, 2025
Fix a few thread-safety bugs to enable test_opcache when run with TSAN:

 * Use relaxed atomics when clearing `ht->_spec_cache.getitem`
   (pythongh-115999)
 * Add temporary suppression for type slot modifications (pythongh-127266)
 * Use atomic load when reading `*dictptr`
(cherry picked from commit f151d27)

Co-authored-by: Sam Gross <[email protected]>
colesbury added a commit that referenced this issue Feb 26, 2025
Fix a few thread-safety bugs to enable test_opcache when run with TSAN:

 * Use relaxed atomics when clearing `ht->_spec_cache.getitem`
   (gh-115999)
 * Add temporary suppression for type slot modifications (gh-127266)
 * Use atomic load when reading `*dictptr`

(cherry picked from commit f151d27)
@kumaraditya303 kumaraditya303 marked this as a duplicate of #131105 Mar 12, 2025
@picnixz picnixz added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Mar 13, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Mar 26, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Mar 27, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Apr 1, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Apr 17, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Apr 22, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Apr 23, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Apr 23, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Apr 25, 2025
nascheme added a commit to nascheme/cpython that referenced this issue Apr 28, 2025
nascheme added a commit that referenced this issue Apr 28, 2025
In the free-threaded build, avoid data races caused by updating type slots
or type flags after the type was initially created.  For those (typically
rare) cases, use the stop-the-world mechanism.  Remove the use of atomics
when reading or writing type flags.  The use of atomics is not sufficient to
avoid races (since flags are sometimes read without a lock and without
atomics) and are no longer required.
nascheme added a commit to nascheme/cpython that referenced this issue Apr 29, 2025
nascheme added a commit that referenced this issue Apr 29, 2025
… (gh-133129)

This is triggering deadlocks in test_opcache.  See GH-133130 for stack trace.
nascheme added a commit to nascheme/cpython that referenced this issue Apr 29, 2025
In the free-threaded build, avoid data races caused by updating type
slots or type flags after the type was initially created.  For those
(typically rare) cases, use the stop-the-world mechanism.  Remove the
use of atomics when reading or writing type flags.  The use of atomics
is not sufficient to avoid races (since flags are sometimes read without
a lock and without atomics) and are no longer required.
nascheme added a commit to nascheme/cpython that referenced this issue Apr 29, 2025
In the free-threaded build, avoid data races caused by updating type
slots or type flags after the type was initially created.  For those
(typically rare) cases, use the stop-the-world mechanism.  Remove the
use of atomics when reading or writing type flags.  The use of atomics
is not sufficient to avoid races (since flags are sometimes read without
a lock and without atomics) and are no longer required.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes 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

4 participants