Single-threaded re-entrancy via a recursive generator causes an access violation (segfault) in `pairwise_next`
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Crash report
What happened?
The existing partial fix in main (the it = po->it; if (it == NULL) re-read guard after the first tp_iternext call) does not cover the second tp_iternext call, where it is still a borrowed reference. In the single-threaded case a re-entrant call can trigger Py_CLEAR(po->it) which drops the generator's refcount to zero and frees it, leaving the outer call's local it as a dangling pointer.
Minimal reproducer:
from itertools import pairwise
def g():
yield next(it)
for _ in range(10000):
try:
it = pairwise(g())
next(it)
except ValueError:
pass
Exception ignored in: <generator object g at 0x...>
ValueError: generator already executing
Windows fatal exception: access violation
This is also the root cause of https://github.com/spyder-ide/qtconsole/issues/635.
Some options to address:
Py_INCREF(it)before the secondtp_iternext(it)call +Py_DECREFafter, or- a re-entrancy guard flag (like
teedataobject.running) as suggested by @rhettinger.
Note: Py_BEGIN_CRITICAL_SECTION (added in PR #144489) does not protect against same-thread re-entrancy.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Output from running 'python -VV' on the command line:
No response
Linked PRs
- gh-150589
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginnen Sie beim Einstiegspunkt pairwise_next und überprüfen Sie den verknüpften PR gh-150589 zusammen mit dem Reproduzierer recursive-generator. Stellen Sie sicher, dass der zweite tp_iternext-Aufruf bei der Reentrancy im selben Thread weiterhin sicher ist, und führen Sie den Reproduzierer erneut aus, um zu bestätigen, dass er nun keine Zugriffsverletzung mehr verursacht.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- c, python
- Bereich
- backend
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 25/100