fix(subinterpreter): don't touch the thread state before create() attaches one (#6127)
`subinterpreter::create()` documents that "the main interpreter and its GIL
are not required to be held prior to calling this function", but its first
statement is `error_scope err_scope;`, i.e. `PyErr_Fetch()`, before
`main_guard` attaches a thread state. With no current `PyThreadState`,
`PyErr_Fetch()` -> `_PyErr_GetRaisedException(NULL)` dereferences null and
the process dies (SIGSEGV; 0xC0000005 on Windows). `~error_scope` is the
mirror image: it calls `PyErr_Restore()` after `main_guard` has already
swapped the thread state back away.
Two ordinary situations reach `create()` with no thread state:
- an embedder that ends its initialization with `PyEval_SaveThread()`,
which is the documented way to hand the GIL back after
`Py_InitializeFromConfig()`;
- any worker thread that has never touched Python.
Existing tests never hit this because they all run under the
`py::scoped_interpreter guard{}` in catch.cpp, which keeps the GIL held on
the main thread for the whole run.
Move `error_scope` inside the `main_guard` scope. The case it exists for is
unaffected: a caller that already holds the main GIL takes
`subinterpreter_scoped_activate`'s `simple_gil_` fast path, which keeps the
same thread state, so its pending error is still saved across
`Py_NewInterpreterFromConfig()` and restored afterwards. A caller sitting on
some other interpreter never had its error indicator touched in the first
place, since everything inside the block runs on the main interpreter's
thread state and `PyThreadState_Swap()` does not move error indicators. It
also makes the `pybind11_fail()` path unwind in a safer order: `~error_scope`
now runs while `main_guard` is still alive.
Add "Create Subinterpreter without a thread state", covering both a thread
that dropped its thread state via `gil_scoped_release` and a thread that
never had one. It segfaults without the fix and passes with it.
Verified on Windows / MSVC 14.51 / CPython 3.13.14: test_with_catch goes
from 33 to 34 test cases, all passing.
Assisted-by: ClaudeCode:claude-opus-52 files changed