You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've been debugging a really nasty segfault in a large (proprietary) python/C++ project which uses pybind11. The following is one possibility I'm considering:
Say you have the following in C++:
classMyClass : publicIntrusiveRefCountedObject { // registered with pybindprivate:
OtherClass otherObj; // also inherits from `IntrusiveRefCountedObject` and registered with pybindpublic:MyClass(OtherClass* otherObj) : otherObj(otherObj) {
otherObj->doSomethingWith(this); // `doSomethingWith` is wrapped with `PYBIND11_OVERRIDE`
}
...
}
And in python:
a=OtherClass()
b=MyClass(a)
Judging from the gdb backtrace, when you create a new instance in python with MyClass(a), the C++ constructor MyClass::MyClass is called before the python instance is initialized with pybind11::class_<...>::init_instance. Therefore, while you're in the MyClass constructor, your ref count is zero.
So when you call otherObj->doSomethingWith(this) (which has been wrapped with PYBIND11_OVERRIDE) while you're in the MyClass constructor, you would need to 1) create a python instance of otherObj to check if doSomethingWith is overridden in python, 2) if it is overridden, create a python instance of this to pass into the python function.
If OtherClass::doSomethingWith is overridden in python, you would immediately cause issues. Since presumably after you're done with the temporary python instance of this, the garbage collector would see the ref count is 0 and free it.
However, for my particular case, OtherClass::doSomethingWith is not overridden in python. And from debugging, I don't think MyClass::~MyClass is being called before pybind11::class_<...>::init_instance. But is it possible that the memory this is supposed to occupy gets freed anyway? Or some other issues happen?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I've been debugging a really nasty segfault in a large (proprietary) python/C++ project which uses pybind11. The following is one possibility I'm considering:
Say you have the following in C++:
And in python:
Judging from the gdb backtrace, when you create a new instance in python with
MyClass(a)
, the C++ constructorMyClass::MyClass
is called before the python instance is initialized withpybind11::class_<...>::init_instance
. Therefore, while you're in theMyClass
constructor, your ref count is zero.So when you call
otherObj->doSomethingWith(this)
(which has been wrapped withPYBIND11_OVERRIDE
) while you're in theMyClass
constructor, you would need to 1) create a python instance ofotherObj
to check ifdoSomethingWith
is overridden in python, 2) if it is overridden, create a python instance ofthis
to pass into the python function.If
OtherClass::doSomethingWith
is overridden in python, you would immediately cause issues. Since presumably after you're done with the temporary python instance ofthis
, the garbage collector would see the ref count is 0 and free it.However, for my particular case,
OtherClass::doSomethingWith
is not overridden in python. And from debugging, I don't thinkMyClass::~MyClass
is being called beforepybind11::class_<...>::init_instance
. But is it possible that the memorythis
is supposed to occupy gets freed anyway? Or some other issues happen?Beta Was this translation helpful? Give feedback.
All reactions