-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
Data race in PyUnicode_AsUTF8AndSize under free-threading #128013
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
Comments
I have a fix at #128021, can you test it? |
Hmm, does this actually end up crashing in practice? Strings are supposed to be immutable (but they aren't), but the reproducer doesn't look like an actual race, because none of the fields will ever be modified concurrently. If it is a race, then I suspect we need to make most of the |
unicodeobject.c is mostly designed on the assumption that newly created strings are freely mutable in any way, and have a reference count of 1. See Only very few functions can "mutate" a string when the refcount is greater than 1. On the other side, |
On the free-threaded build, all strings are immortal, so we can't check the reference count. |
It did not crash in practice. But just reading the code, this looks racy: cpython/Objects/unicodeobject.c Line 5865 in 7303f06
The The proposed fix looks reasonable to me. |
I can confirm the fix appears to fix the tsan warning. |
Yeah, I think that makes sense. We should probably use
String literals are immortal, but not all strings are immortal. |
Convert unicodeobject.c macros to static inline functions. * Add _PyUnicode_SET_UTF8() and _PyUnicode_SET_UTF8_LENGTH() macros. * Add PyUnicode_HASH() and PyUnicode_SET_HASH() macros. * Remove unused _PyUnicode_KIND() and _PyUnicode_GET_LENGTH() macros.
Convert unicodeobject.c macros to static inline functions. * Add _PyUnicode_SET_UTF8() and _PyUnicode_SET_UTF8_LENGTH() macros. * Add PyUnicode_HASH() and PyUnicode_SET_HASH() macros. * Remove unused _PyUnicode_KIND() and _PyUnicode_GET_LENGTH() macros.
Convert unicodeobject.c macros to static inline functions. * Add _PyUnicode_SET_UTF8() and _PyUnicode_SET_UTF8_LENGTH() macros. * Add PyUnicode_HASH() and PyUnicode_SET_HASH() macros. * Remove unused _PyUnicode_KIND() and _PyUnicode_GET_LENGTH() macros.
…128061) Convert unicodeobject.c macros to static inline functions. * Add _PyUnicode_SET_UTF8() and _PyUnicode_SET_UTF8_LENGTH() macros. * Add PyUnicode_HASH() and PyUnicode_SET_HASH() macros. * Remove unused _PyUnicode_KIND() and _PyUnicode_GET_LENGTH() macros.
…128061) Convert unicodeobject.c macros to static inline functions. * Add _PyUnicode_SET_UTF8() and _PyUnicode_SET_UTF8_LENGTH() macros. * Add PyUnicode_HASH() and PyUnicode_SET_HASH() macros. * Remove unused _PyUnicode_KIND() and _PyUnicode_GET_LENGTH() macros.
Bug report
Bug description:
Repro: build this C extension (
race.so
) with free threading enabled, with a CPython built with thread-sanitizer enabled:and run this python module:
I built the module with
-fsanitize=thread
(clang-18 -fsanitize=thread t.c -shared -o race.so -I ~/p/cpython-tsan/include/python3.13t/
) although I doubt it matters a whole lot.After running it a few times on my machine, I received the following thread-sanitizer report:
I'd guess that this CPython code really needs to hold a mutex:
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs
The text was updated successfully, but these errors were encountered: