PyObject_Call
segfaults when it is called with an instance of a bound method, but works fine when invoked with regular (unbound) procedures or with an instance of a class that implements __call__
, or with subclasses of type
.
Any reason it should work like this, or is this a bug? The behavior is consistent between v 3.5 and 3.6. Didn't try earlier versions.
PS. The stacktrace produced in this scenario doesn't even contain my code. However, if it matters, the crash happens inside
method_dealloc () at Objects/classobject.c:194
which looks like this: https://github.com/python/cpython/blob/master/Objects/classobject.c#L194
To prevent the immediate question: yes, I call Py_INCREF(callable)
before calling this procedure.
More info
When I try to look at what is being sent into this call, I see something like this:
found method: <bound method DefParser.parse of <bound method DefParser.update_definition of <NULL>>>
The DefParser.parse
and DefParser.update_definition
are not exactly random, but also not exactly relevant: they are methods that have been called recently. I.e. I suspect that PyObject_Call
itself isn't guilty, it's just the way method objects are represented... for some reason I seem to lose the reference, and instead hold on to garbage...
A lot of investigation found the actual error. It wasn't related to PyObject_Call
in the end, but it may help others who might run into this situation.
PyObject_Call
is one of the Python C API which allocates memory. Python's memory allocator will opportunistically call GC. I'm not sure on specifics of when it decides to do it, but eventually it will happen. GC will then try to free memory allocated by Python objects.
What happened in my case: there was a string allocated using regular malloc
, where I miscalculated the position of the terminating null-byte (in some cases it would appear one position after the memory I requested to be allocated). This memory was then used to create a Python bytes
object. Later one, when GC would de-allocate this object, it would seagfault.