Skip to content

Commit cb5a5a5

Browse files
committed
Make sure python is alive before DECREFing
If something triggers internals to be created during finalization, it might end up being destroyed after finalization and we don't want to do the DECREF at that point, we need the leaky behavior.
1 parent 50c319d commit cb5a5a5

1 file changed

Lines changed: 22 additions & 9 deletions

File tree

include/pybind11/detail/internals.h

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,17 @@ struct internals {
309309
internals &operator=(const internals &other) = delete;
310310
internals &operator=(internals &&other) = delete;
311311
~internals() {
312-
Py_XDECREF(static_property_type);
313-
static_property_type = nullptr;
314-
315-
Py_XDECREF(default_metaclass);
316-
default_metaclass = nullptr;
312+
// Normally this destructor runs during interpreter finalization and it may DECREF things.
313+
// In odd finalization scenarios it might end up running after the interpreter has
314+
// completely shut down, In that case, we should not decref these objects because pymalloc
315+
// is gone.
316+
if (Py_IsInitialized()) {
317+
Py_XDECREF(static_property_type);
318+
static_property_type = nullptr;
319+
320+
Py_XDECREF(default_metaclass);
321+
default_metaclass = nullptr;
322+
}
317323
}
318324
};
319325

@@ -333,8 +339,14 @@ struct local_internals {
333339
PyTypeObject *function_record_py_type = nullptr;
334340

335341
~local_internals() {
336-
Py_XDECREF(function_record_py_type);
337-
function_record_py_type = nullptr;
342+
// Normally this destructor runs during interpreter finalization and it may DECREF things.
343+
// In odd finalization scenarios it might end up running after the interpreter has
344+
// completely shut down, In that case, we should not decref these objects because pymalloc
345+
// is gone.
346+
if (Py_IsInitialized()) {
347+
Py_XDECREF(function_record_py_type);
348+
function_record_py_type = nullptr;
349+
}
338350
}
339351
};
340352

@@ -717,8 +729,9 @@ class internals_pp_manager {
717729
pp->reset();
718730
}
719731
// Because the unique_ptr is still pointed to by the pp_manager in this and possibly other
720-
// modules, we cannot free the unique_ptr itself until after the interpreter has shut down.
721-
// If this interpreter was not created/owned by pybind11 then this unique_ptr is leaked.
732+
// modules, we cannot delete the unique_ptr itself until after the interpreter has shut
733+
// down. If this interpreter was not created/owned by pybind11 then the unique_ptr itself
734+
// (but not its contents) is leaked.
722735
}
723736

724737
std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict() {

0 commit comments

Comments
 (0)