`groupby_next` data race on free-threaded builds
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
Bug report
Bug description:
Two threads calling next on the same groupby object concurrently in a free-threaded build race on the currgrouper field, corrupting the iterator's internal state and producing AttributeError on slot accesses of live objects.
groupby_next has no Py_BEGIN_CRITICAL_SECTION guard. The first thing it does is write gbo->currgrouper = NULL:
Later, after the loop exits, it calls _grouper_create, which writes parent->currgrouper = igo:
If Thread A is past line 633 (just stored the new grouper pointer) while Thread B is at line 537 (about to store NULL), Thread B overwrites the pointer Thread A just wrote. Both are plain pointer stores with no synchronisation.
The following script reproduces the condition under which this happens.
import itertools, threading
class K:
__slots__ = ("v",)
def __init__(self, v): self.v = v
def __eq__(self, o): return isinstance(o, K) and self.v == o.v
def __hash__(self): return hash(self.v)
def consume(g):
try:
while True:
_, _ = next(g)
except StopIteration:
pass
keys = [K(i) for i in range(500_000)]
g = itertools.groupby(keys)
threads = [threading.Thread(target=consume, args=(g,)) for _ in range(8)]
for t in threads: t.start()
for t in threads: t.join()
On a free-threaded build, this results in the following Python logs...
Exception in Thread-15 (consume):
File "<python-input-2>", line 6, in __eq__
def __eq__(self, o): return isinstance(o, K) and self.v == o.v
^^^^^^
AttributeError: 'K' object has no attribute 'v'
... and the following TSan logs.
WARNING: ThreadSanitizer: data race (pid=20464)
Write of size 8 at 0x0003026e4a88 by thread T2:
#0 groupby_next itertoolsmodule.c:537 (python.exe:arm64+0x10042a8b8)
#1 builtin_next bltinmodule.c:1770
Previous write of size 8 at 0x0003026e4a88 by thread T1:
#0 _grouper_create itertoolsmodule.c:633 (python.exe:arm64+0x10042ac5c)
#1 groupby_next itertoolsmodule.c:570 (python.exe:arm64+0x10042ac5c)
#2 builtin_next bltinmodule.c:1770
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-150792
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez dans Modules/itertoolsmodule.c, au niveau de groupby_next et _grouper_create, puis exécutez le reproducer concurrent fourni sur un build free-threaded avec ThreadSanitizer. Le travail est terminé lorsque le reproducer ne signale plus la race de currgrouper et ne produit plus l’AttributeError décrit.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- c, python
- Domaine
- backend, testing-qa
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 25/100