Harden PYBIND11_MODULE_PYINIT and get_internals() against crashes during module init#6018
Merged
rwgk merged 2 commits intopybind:masterfrom Mar 29, 2026
Merged
Conversation
Previously, ensure_internals() was called without exception handling in the PyInit_* function (PYBIND11_MODULE_PYINIT), while the same call in PYBIND11_MODULE_EXEC was already wrapped in try-catch. On MSVC, a C++ exception propagating through the extern "C" PyInit_* boundary is undefined behavior, which can manifest as an access violation instead of a clean error message. This is a potential contributor to crashes like pybindgh-5993. Wrap the entire PyInit body in try/catch using the existing PYBIND11_CATCH_INIT_EXCEPTIONS pattern. Made-with: Cursor
Add explicit null checks after get_pp() and create_pp_content_once() in get_internals(), calling pybind11_fail() with descriptive messages. These guards convert potential null-pointer dereferences (which produce unhelpful access-violation crashes, especially on Windows) into clear runtime_error messages that can be caught and reported as ImportError by the try-catch added in the previous commit. Made-with: Cursor
3 tasks
rwgk
added a commit
to rwgk/pybind11
that referenced
this pull request
Mar 30, 2026
… during module init (pybind#6018) * Wrap ensure_internals() in try-catch in PYBIND11_MODULE_PYINIT Previously, ensure_internals() was called without exception handling in the PyInit_* function (PYBIND11_MODULE_PYINIT), while the same call in PYBIND11_MODULE_EXEC was already wrapped in try-catch. On MSVC, a C++ exception propagating through the extern "C" PyInit_* boundary is undefined behavior, which can manifest as an access violation instead of a clean error message. This is a potential contributor to crashes like pybindgh-5993. Wrap the entire PyInit body in try/catch using the existing PYBIND11_CATCH_INIT_EXCEPTIONS pattern. Made-with: Cursor * Add nullptr guards in get_internals() for better crash diagnostics Add explicit null checks after get_pp() and create_pp_content_once() in get_internals(), calling pybind11_fail() with descriptive messages. These guards convert potential null-pointer dereferences (which produce unhelpful access-violation crashes, especially on Windows) into clear runtime_error messages that can be caught and reported as ImportError by the try-catch added in the previous commit. Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Motivated by the crash reports in #5993 (v3.0.2 regression: access violation in
get_internalsduring module import on Windows / Python 3.10–3.11):Wrap the body of
PYBIND11_MODULE_PYINIT(thePyInit_*function) intry / PYBIND11_CATCH_INIT_EXCEPTIONS, matching the pattern already used inPYBIND11_MODULE_EXEC. Previously, any C++ exception thrown byensure_internals()during phase-1 module init would propagate through theextern "C"PyInit_*boundary — undefined behavior on MSVC that can manifest as an access violation rather than a clean error.Add explicit
nullptrguards withpybind11_fail()inget_internals()afterget_pp()andcreate_pp_content_once(), converting silent null-pointer dereferences into actionable error messages.Suggested changelog entry:
PYBIND11_MODULE_PYINITbody in try-catch to prevent C++ exceptions from propagating through theextern "C"PyInit_*boundary (undefined behavior on MSVC, could cause access violations instead of clean error messages). Addednullptrguards inget_internals()for improved crash diagnostics.