Harden `PYBIND11_MODULE_PYINIT` and `get_internals()` against crashes during module init (#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 gh-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
diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h
index ebffe57..d438f9c 100644
--- a/include/pybind11/detail/common.h
+++ b/include/pybind11/detail/common.h
@@ -457,19 +457,24 @@
     static int PYBIND11_CONCAT(pybind11_exec_, name)(PyObject *);                                 \
     PYBIND11_PLUGIN_IMPL(name) {                                                                  \
         PYBIND11_CHECK_PYTHON_VERSION                                                             \
-        pybind11::detail::ensure_internals();                                                     \
-        static ::pybind11::detail::slots_array mod_def_slots = ::pybind11::detail::init_slots(    \
-            &PYBIND11_CONCAT(pybind11_exec_, name), ##__VA_ARGS__);                               \
-        static PyModuleDef def{/* m_base */ PyModuleDef_HEAD_INIT,                                \
-                               /* m_name */ PYBIND11_TOSTRING(name),                              \
-                               /* m_doc */ nullptr,                                               \
-                               /* m_size */ 0,                                                    \
-                               /* m_methods */ nullptr,                                           \
-                               /* m_slots */ mod_def_slots.data(),                                \
-                               /* m_traverse */ nullptr,                                          \
-                               /* m_clear */ nullptr,                                             \
-                               /* m_free */ nullptr};                                             \
-        return PyModuleDef_Init(&def);                                                            \
+        try {                                                                                     \
+            pybind11::detail::ensure_internals();                                                 \
+            static ::pybind11::detail::slots_array mod_def_slots                                  \
+                = ::pybind11::detail::init_slots(&PYBIND11_CONCAT(pybind11_exec_, name),          \
+                                                 ##__VA_ARGS__);                                  \
+            static PyModuleDef def{/* m_base */ PyModuleDef_HEAD_INIT,                            \
+                                   /* m_name */ PYBIND11_TOSTRING(name),                          \
+                                   /* m_doc */ nullptr,                                           \
+                                   /* m_size */ 0,                                                \
+                                   /* m_methods */ nullptr,                                       \
+                                   /* m_slots */ mod_def_slots.data(),                            \
+                                   /* m_traverse */ nullptr,                                      \
+                                   /* m_clear */ nullptr,                                         \
+                                   /* m_free */ nullptr};                                         \
+            return PyModuleDef_Init(&def);                                                        \
+        }                                                                                         \
+        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \
+        return nullptr;                                                                           \
     }
 
 #define PYBIND11_MODULE_EXEC(name, variable)                                                      \
diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h
index 7edd004..4175d20 100644
--- a/include/pybind11/detail/internals.h
+++ b/include/pybind11/detail/internals.h
@@ -862,7 +862,11 @@
 /// Return a reference to the current `internals` data
 PYBIND11_NOINLINE internals &get_internals() {
     auto &ppmgr = get_internals_pp_manager();
-    auto &internals_ptr = *ppmgr.get_pp();
+    auto *pp = ppmgr.get_pp();
+    if (!pp) {
+        pybind11_fail("get_internals: get_pp() returned nullptr");
+    }
+    auto &internals_ptr = *pp;
     if (!internals_ptr) {
         // Slow path, something needs fetched from the state dict or created
         gil_scoped_acquire_simple gil;
@@ -870,6 +874,9 @@
 
         ppmgr.create_pp_content_once(&internals_ptr);
 
+        if (!internals_ptr) {
+            pybind11_fail("get_internals: create_pp_content_once() produced nullptr");
+        }
         if (!internals_ptr->instance_base) {
             // This calls get_internals, so cannot be called from within the internals constructor
             // called above because internals_ptr must be set before get_internals is called again