Skip to content

Having a class which holds the same pointer inside can crash #1568

Closed
@novoselov-ab

Description

@novoselov-ab

Issue description

Having a class which holds the same pointer inside can crash.
The essence of the problem is that register_instance and deregister_instance search all instances with the same pointer and then select with matching type: Py_TYPE(self) == Py_TYPE(it->second). In certain situations there could be multiple instance of the same type and same pointer.

Reproducible example code

This class can cause a problem:

    struct SamePointer {};
    static SamePointer samePointer;

    py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, "SamePointer").def(py::init<>([&]() {
        return &samePointer;
    }));

To reproduce you need regular simple class:

    struct Empty {};
    py::class_<Empty> (m, "Empty")
        .def(py::init<>());

And this python code

import m
x = []
for _ in range(100):
    x.append(m.SamePointer())

for j in range(2):
    for i in range(100):
        if i % 2 == j:
            x[i] = m.Empty()

Creating other python classes will reuse the same python object, which was meant to be freed by python, but still considered valid by pybind.
This line will be triggered pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!");


Maybe it is a bad idea to write a class this way, but it was non obvious and took a lot of time to catch a failure and debug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions