pybind11 icon indicating copy to clipboard operation
pybind11 copied to clipboard

[BUG]: Simply creating subinterpreter leaks memory

Open justend29 opened this issue 4 months ago • 3 comments

Required prerequisites

  • [x] Make sure you've read the documentation. Your issue may be addressed there.
  • [x] Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
  • [x] Consider asking first in the Gitter chat room or in a Discussion.

What version (or hash if on master) of pybind11 are you using?

90bc05c

Problem description

The mere use of a subinterpreter leaks memory. Memory leaks were found with python 3.12 and 3.13 For example:

#include <pybind11/embed.h>
#include <pybind11/subinterpreter.h>

int main() {
  pybind11::initialize_interpreter();
  const auto sub_python = pybind11::subinterpreter::create();
}

From the pybind11 project source, I am building this minimal example with the following command

g++ test.cpp -fsanitize=address  -I /usr/include/python3.13 -I ./include -l python3.13

Reference of g++ version:

g++ --version
g++ (GCC) 15.1.1 20250729
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The sanitizer's output is included as an attachment: sanitizer.txt

Reproducible example code

#include <pybind11/embed.h>
#include <pybind11/subinterpreter.h>

int main() {
  pybind11::initialize_interpreter();
  const auto sub_python = pybind11::subinterpreter::create();
}

Is this a regression? Put the last known working version here if it is.

Not a regression

justend29 avatar Aug 12 '25 22:08 justend29

CC @b-pass, though I think I remember this might be intentional, since there are rules about keeping it alive?

henryiii avatar Aug 13 '25 14:08 henryiii

There are a lot of leaks from internal python modules, there's not really anything that we can do about those. There are a few things that are leaking from pybind11 internals. We do clean up the internals itself, but we don't clean up the ~3 types that internals creates (static property, meta class, and function record).

This was always leaking, but it was less of an issue when there was only one interpreter because creating and destroying it multiple times in one program was more rare. With sub-interpreters, it can happen a lot more.

Fixing it will probably be tricky because we don't have a lot of control over the destruction order of things in python which might make calls back into pybind11 during sub-interpreter destruction. So, if we DECREF these things during shutdown then python might subsequently delete them.... for example, the base HeapType for all pybind11 objects.

b-pass avatar Aug 14 '25 01:08 b-pass

@b-pass If you attach a destructor to the capsule object that stores the internals pointer, it should be pretty safe at that point to free everything owned by internals. Rationale:

  • clearing the interpreter state dict (where the capsule is stored) is basically the final step during interpreter finalization
  • with no references to the capsule, later code wouldn't be able to find the half-destroyed internals; it would create a new one (which would probably leak but that seems fine for this edge case)

oremanj avatar Dec 02 '25 18:12 oremanj