An unexpected visit_decref assertion violation (code works with 2.4, not with 2.5)
Hello,
I have a Python module here that takes a bunch of C++ classes, and turns them into Python classes. When built against and loaded into Python 2.4, everything is fine. But when built against and loaded into Python 2.5, I get an assert violation from Python's gc module. Here is the code that is failing:
klass = PyClass_New(bases, classDict, className);
if (klass && methods) {
/* add methods to class */
for (def = methods; def->ml_name != NULL; def++) {
printf( "IlmPyClass: %d, def = %s\n", __LINE__, def->ml_name);
PyObject *func = IlmPyClass_NewFunction(def);
if (!func) {
Py_XDECREF(klass);
return NULL;
}
printf( "We get here\n" );
func = PyMethod_New(func, NULL, klass); //this line fails
printf( "We don't get here\n" );
# .......
}
}
The output of 'python2.5 -c "import mymod"' is:
""" [.... snip a bunch of "we get here, we don't get here" etc. as things fail to fail...] IlmPyClass: 197, def = __init__ We get here python2: Modules/gcmodule.c:276: visit_decref: Assertion `gc->gc.gc_refs != 0' failed.
Abort """
The obvious things, such as Py_INCREFing klass or func, do not work.
What's extra strange, in addition to this code working fine in an earlier python version, is that this code works fine for most of the classes that are instantiated.
What I really want to do, though, is see what exactly is being decref'd. Does anyone have any tips for doing this? I've already tried using a debug build of Python; it doesn't seem to provide that type of ref tracing. Thanks in advance for any tips or insights.
-- Joe Ardent
Hi Joe, Start off by saying I don't know the answer to your problem, but will try give some hints. Unless anyone else has encountered this problem you could also mail the python dev's about this too since they are more likely to know about changes in pythons internals. Though with obscure changes in python I have found your usually on your own :| You might better pinpoint the cause of the problem by building python from svn and finding the revision that broke it.
For doing any py/C api work I find it essential to build my own python and keep the source in the build dir so I can step through python internals. the configure flag for debugging didnt work well for me either so I build wth ./configure --prefix=/opt/python/ --with-pydebug make CFLAGS="-O0 -g3 -fno-inline"; make install
Maybe this is obvious too but in gdb some useful commands when stepping through pythons internals (where ob is a PyObject). p *ob->ob_type ...lets you quickly see the type which can give you a hint as to whats going on p PyObject_Print(ob, stderr, 0)
Should probably use gdb macro's but I have this function for quicker printing, also means you dont have to check for NULL values before printing (which will segfault).
void PyObSpit(char *name, PyObject *var) { fprintf(stderr, "<%s> : ", name); if (var==NULL) { fprintf(stderr, "<NIL>"); } else { PyObject_Print(var, stderr, 0); } fprintf(stderr, "\n"); }
Interesting converting C++ to python, out of interest are you inheriting the C++ class as a PyObject? for Blender3D's game engine api I recently reworked some of the python/C++ integration based on an API from 1997! http://www.python.org/doc/PyCPP.html We have our own ref-counting going on, so this mixed with pythons quite badly - now the PyObjects are member of the class which I find more flexible.
On Thu, Apr 30, 2009 at 12:30 PM, Joe Ardent <jardent@ilm.com> wrote:
Hello,
I have a Python module here that takes a bunch of C++ classes, and turns them into Python classes. When built against and loaded into Python 2.4, everything is fine. But when built against and loaded into Python 2.5, I get an assert violation from Python's gc module. Here is the code that is failing:
klass = PyClass_New(bases, classDict, className); if (klass && methods) { /* add methods to class */ for (def = methods; def->ml_name != NULL; def++) { printf( "IlmPyClass: %d, def = %s\n", __LINE__, def->ml_name);
PyObject *func = IlmPyClass_NewFunction(def); if (!func) { Py_XDECREF(klass); return NULL; } printf( "We get here\n" ); func = PyMethod_New(func, NULL, klass); //this line fails printf( "We don't get here\n" ); # ....... } }
The output of 'python2.5 -c "import mymod"' is:
""" [.... snip a bunch of "we get here, we don't get here" etc. as things fail to fail...] IlmPyClass: 197, def = __init__ We get here python2: Modules/gcmodule.c:276: visit_decref: Assertion `gc->gc.gc_refs != 0' failed.
Abort """
The obvious things, such as Py_INCREFing klass or func, do not work.
What's extra strange, in addition to this code working fine in an earlier python version, is that this code works fine for most of the classes that are instantiated.
What I really want to do, though, is see what exactly is being decref'd. Does anyone have any tips for doing this? I've already tried using a debug build of Python; it doesn't seem to provide that type of ref tracing. Thanks in advance for any tips or insights.
-- Joe Ardent
capi-sig mailing list capi-sig@python.org http://mail.python.org/mailman/listinfo/capi-sig
--
- Campbell
participants (2)
-
Campbell Barton
-
Joe Ardent