-1

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...

Xantium
  • 11,201
  • 10
  • 62
  • 89
wvxvw
  • 8,089
  • 10
  • 32
  • 61
  • Shouldn't this have the `cpython` and `c` tags, not `python`? – FHTMitchell Jun 18 '18 at 14:46
  • 1
    Well, this is about Python, the last time I checked. Probably C programmers will not find this question very interesting / on topic. I'll add CPython. – wvxvw Jun 18 '18 at 15:04
  • I suppose. My interpretation of the tag is that you are using that language/tool/framework. If you're developing it, then the correct tag is whatever you are developing with. But it's no big deal :) – FHTMitchell Jun 18 '18 at 15:06
  • 1
    @FHTMitchell I think the `python-c-api` tag is more appropriate here. `cpython` may not be realated to C, but may be issues with `cpython` specifically (that do not appear in other Python inplamentations). – Xantium Jun 18 '18 at 15:31
  • 1
    I've downvoted and voted to close because there isn't an [mcve]. This should (and does) work, and the issue is elsewhere in your code. I'm happy to remove these votes if the question is improved, but it's currently unanswerable – DavidW Jun 18 '18 at 18:37
  • @DavidW your opinion is very important to me. Keep it coming. – wvxvw Jun 18 '18 at 19:17

1 Answers1

-1

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.

wvxvw
  • 8,089
  • 10
  • 32
  • 61