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 spyder-ide/qtconsole#635.
Some options to address:
Py_INCREF(it) before the second tp_iternext(it) call + Py_DECREF after, 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
Crash report
What happened?
The existing partial fix in
main(theit = po->it; if (it == NULL)re-read guard after the firsttp_iternextcall) does not cover the secondtp_iternextcall, whereitis still a borrowed reference. In the single-threaded case a re-entrant call can triggerPy_CLEAR(po->it)which drops the generator's refcount to zero and frees it, leaving the outer call's localitas a dangling pointer.Minimal reproducer:
This is also the root cause of spyder-ide/qtconsole#635.
Some options to address:
Py_INCREF(it)before the secondtp_iternext(it)call +Py_DECREFafter, orteedataobject.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