boostorg / boostorg/python

with_custodian_and_ward doesn't guarantee destructor ordering

Offen
#128 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
C++
Sterne
537
Forks
223
Ø Merge
11 Std. 22 Min.
Gemergte PRs (30 T.)
2

Beschreibung

The weakref trick used by `with_custodian_and_ward` relies on the nurse object being cleared before it calls the callback which drops the reference to the patient. This is mostly but not always true: when the cyclic garbage collector runs, it first makes all weakref callbacks before freeing the garbage (at least in Python 2.7.12). This can lead to the patient's destructor running before the nurse's, with dire consequences if the nurse references the patient in its destructor.

pybind11 uses the same weakref trick and suffers the same bug: https://github.com/pybind/pybind11/issues/856.

## Example code

keepalive.cpp:
```c++
#include
#include

namespace py = boost::python;

class B;

class A {
private:
B &b;
public:
A(B &b) : b(b) {}
~A() { std::cerr << "In A::~A()\n"; }
};

class B {
public:
~B() { std::cerr << "In B::~B()\n"; }
};

BOOST_PYTHON_MODULE(keepalive) {
py::class_("A", py::init()[py::with_custodian_and_ward<1, 2>()]);
py::class_("B");
}
```

test.py:
```python
#!/usr/bin/env python
from keepalive import A, B

lst = [A(B())]
lst.append(lst)
del lst
```

Output:
```
In B::~B()
In A::~A()
```

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Rechercherichtung

Start with the reproducer in keepalive.cpp and test.py, then run it under the affected garbage-collection scenario described in the issue. Trace with_custodian_and_ward's weakref callback and destructor behavior; done means the patient's lifetime cannot end before the nurse when cyclic garbage collection occurs.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
cpp, python
Bereich
api, backend
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
30/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.