-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
Segfault in union_repr
from list_repr_impl
in free-threaded build
#132713
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
Here's a reduced repro in case it helps: import abc
from threading import Thread
from typing import Union
class NonUniqueMeta(abc.ABCMeta):
i = 0
def __hash__(self):
self.i += 1
return self.i
class NonUnique(metaclass=NonUniqueMeta): pass
nonun = (NonUnique,) * 350
big_union = Union[*nonun]
for x in range(100):
alive = []
obj = []
alive.append(Thread(target=obj.__str__, args=()))
alive.append(Thread(target=obj.__str__, args=()))
alive.append(Thread(target=obj.clear, args=()))
obj.append([big_union] * 100)
for obj in alive:
obj.start() |
Looks like the whole |
cc @colesbury and @JelleZijlstra |
Hmm. I don't see how the issue could be with |
Two different issues: List can be modified concurrently or reentrantly during Lines 606 to 608 in ea8ec95
Lazy initialization of Lines 329 to 335 in ea8ec95
|
Hold a strong reference to the item while calling repr(item).
Hold a strong reference to the item while calling repr(item).
Hold a strong reference to the item while calling repr(item).
I wrote #132801 to fix this issue. |
Use a critical section in union_getitem() to initialize the 'parameters' member.
Oh, right, I wrote #132802 to fix this other (minor) issue. |
Hold a strong reference to the item while calling repr(item).
Hold a strong reference to the item while calling repr(item). (cherry picked from commit a4ea80d)
Add union_init_parameters() helper function. Use a critical section to initialize the 'parameters' member.
Fixed. Thanks for the bug report @devdanzin. |
) Add union_init_parameters() helper function. Use a critical section to initialize the 'parameters' member. (cherry picked from commit dc3e963) Co-authored-by: Victor Stinner <vstinner@python.org>
Fusil has hit a very similar crash while running an outdated commit of main, also pointing to union repr, but this time from a classmethod repr. It makes be wonder whether the same issue we had in list repr is present for classmethod. Here's the traceback. Should a new issue be created for this, or are the current fixes enough? I can try to get a MRE if it's interesting.
|
Is it still reproducible on latest main? If classmethods are mutable they may need a similar fix to list. |
It's reproducible in latest main, just checked (will double check when I get on a computer). |
Would you mind to open a new issue? |
I reduced the test case and it depends on calling Sorry for the noise. import abc
import builtins
import collections.abc
import itertools
import types
import typing
from functools import reduce
from operator import or_
abc_types = [cls for cls in abc.__dict__.values() if isinstance(cls, type)]
builtins_types = [cls for cls in builtins.__dict__.values() if isinstance(cls, type)]
collections_abc_types = [cls for cls in collections.abc.__dict__.values() if isinstance(cls, type)]
collections_types = [cls for cls in collections.__dict__.values() if isinstance(cls, type)]
itertools_types = [cls for cls in itertools.__dict__.values() if isinstance(cls, type)]
types_types = [cls for cls in types.__dict__.values() if isinstance(cls, type)]
typing_types = [cls for cls in typing.__dict__.values() if isinstance(cls, type)]
all_types = (abc_types + builtins_types + collections_abc_types + collections_types + itertools_types
+ types_types + typing_types)
all_types = [t for t in all_types if not issubclass(t, BaseException)]
BIG_UNION = reduce(or_, all_types, int)
from threading import Thread
union_cm = classmethod(int | BIG_UNION)
def stress_cm():
for x in range(3):
repr(union_cm)
union_cm.__init__(str|BIG_UNION)
repr(union_cm)
alive = []
for x in range(10):
alive.append(Thread(target=stress_cm, args=()))
for t in alive:
t.start()
for t in alive:
t.join() |
Hold a strong reference to the callable while calling repr(classmethod).
I wrote a basic fix for repr(classmethod): #132899. But this fix was not enough, the reproducer still crashed randomly. A full fix would require to harden classmethod constructor ( |
Crash report
What happened?
Calling
repr
in many threads on a list containing a largetyping.Union
segfaults in a free-threaded build:Example segfault backtrace:
Once it aborted with message:
Found using fusil by @vstinner.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.14.0a7+ experimental free-threading build (heads/main:741c6386b86, Apr 18 2025, 15:04:45) [Clang 19.1.7 (++20250114103320+cd708029e0b2-1
exp120250114103432.75)]Linked PRs
The text was updated successfully, but these errors were encountered: