
Tanguy Fautre <tanguy.fautre@spaceapplications.com> writes:
Hi,
I have an object "m_RegisterEvents" which holds a reference to a Python function. This Python function is a callback given by a Python script.
To call this function, I simply do:
void subsystem_script::register_events() { m_RegisterEvents(); }
And it works.
However, if a Python exception is thrown (and converted to the C++ exception boost::python::error_already_set), I get a segfault in the following function (m_ptr is null, hence the segfault):
inline api::object_base::~object_base() { Py_DECREF(m_ptr); }
This destructor is directly called at the end of the subsystem_script::register_events() function, leading me to believe that it is a temporary object being destructed.
Well, are you sure you're not doing something illegal somewhere? It's supposed to be an invariant that object (and object_base) never has a null m_ptr. That's why we're not using Py_XDECREF. So, either Boost.Python is doing something to break that invariant, or some code (maybe yours, maybe mine) is incorrectly initializing that object, or there's a bug in the compiler's exception unwinding.
The funny thing is that if I do the following, then it works again.
void subsystem_script::register_events() { try { m_RegisterEvents(); }
catch (const error_already_set &) {
} }
However, doing a "throw;" in the catch to re-throw the exception does the same segfault. Converting the exception by throwing another object (e.g. std::runtime_error()) works.
I must admit that I'm totally puzzled.
Very strange. All I can say is what I always tell people: reduce your example to a _truly_ minimal one that reproduces the behavior (one C++ file and one python file) and either you'll discover what you did wrong or you'll give me enough to fix the problem. And please bring your Boost.Python questions to the C++-sig <http://boost.org/more/mailing_lists.htm#cplussig>. -- Dave Abrahams Boost Consulting www.boost-consulting.com