From: Chris S. <chr...@gm...> - 2007-06-15 02:35:57
|
I'm using PyODE with Cherrypy, and whenever the server's autoreload feature runs, Python segfaults with the error: python: Modules/gcmodule.c:276: visit_decref: Assertion `gc->gc.gc_refs != 0' failed. However, Python only segfaults if I've imported ode in any of my Cherrypy scripts. Based on discussions of similar problems, the cause is likely a bug in ODE's C code generated by Pyrex. I wouldn't know where to begin debugging such a problem. Could anyone offer suggestions? Thanks, Chris |
From: Chris B. <chr...@gm...> - 2007-06-15 13:12:41
|
On 15/06/07, Chris Spencer <chr...@gm...> wrote: > I'm using PyODE with Cherrypy, and whenever the server's autoreload > feature runs, Python segfaults with the error: > > python: Modules/gcmodule.c:276: visit_decref: Assertion > `gc->gc.gc_refs != 0' failed. > > However, Python only segfaults if I've imported ode in any of my > Cherrypy scripts. > > Based on discussions of similar problems, the cause is likely a bug in > ODE's C code generated by Pyrex. I wouldn't know where to begin > debugging such a problem. Could anyone offer suggestions? The problem is that the destructor order is essentially random when gc is used. ODE (not pyode) doesn't have any ownership rules for objects, and objects point to each other, so deallocating objects causes memory protection faults. This is also a problem with C++ ODE code, python with gc just aggravates the problem. In my Simulator.__del__ function I have something like: for j in self.joints: j.attach(None, None) for g in self.space: if g.placeable(): g.setBody(None) # destroy hanging geoms ode._geom_c2py_lut.clear() del self.joints del self.space del self.geoms for bg in self.bpgs: bg.destroy() As you can see, I have to manually remove links between objects, and then destroy them all n a particular order. I don't use gc. You can see the memory errors by running valgrind, it will generate loads of warnings; use suppression files, http://svn.python.org/projects/python/trunk/Misc/valgrind-python.supp and opengl.supp from http://www.openscenegraph.com/index.php?page=Documentation.TipsAndTricks There's a bug report for ODE at https://sourceforge.net/tracker/?func=detail&atid=382799&aid=1566350&group_id=24884 |
From: Chris S. <chr...@gm...> - 2007-06-15 19:07:47
|
On 6/15/07, Chris Bainbridge <chr...@gm...> wrote: > > The problem is that the destructor order is essentially random when gc > is used. ODE (not pyode) doesn't have any ownership rules for objects, > and objects point to each other, so deallocating objects causes memory > protection faults. This is also a problem with C++ ODE code, python > with gc just aggravates the problem. In my Simulator.__del__ function > I have something like: [snip] Thanks for the tips. I tried implementing a similar __del__ for my top-level object, but I still encounter the problem. Since it looks like this problem isn't going to be fixed anytime soon, is there anyway to work around the issue? With my usage, the fault only happens when the Python process is terminating, but it's stopping a new process from being spawned. Is there any way to recover from it, or is this problem fatal? Chris |
From: Chris B. <chr...@gm...> - 2007-06-18 12:59:57
|
On 15/06/07, Chris Spencer <chr...@gm...> wrote: > On 6/15/07, Chris Bainbridge <chr...@gm...> wrote: > > > > The problem is that the destructor order is essentially random when gc > > is used. ODE (not pyode) doesn't have any ownership rules for objects, > > and objects point to each other, so deallocating objects causes memory > > protection faults. This is also a problem with C++ ODE code, python > > with gc just aggravates the problem. In my Simulator.__del__ function > > I have something like: > [snip] > > Thanks for the tips. I tried implementing a similar __del__ for my > top-level object, but I still encounter the problem. Are you sure your __del__ function is being called first? You might need to rename it and manually call it from your shutdown function before python starts garbage collecting. > Since it looks like this problem isn't going to be fixed anytime soon, > is there anyway to work around the issue? With my usage, the fault > only happens when the Python process is terminating, but it's stopping > a new process from being spawned. Is there any way to recover from it, > or is this problem fatal? You can ignore the return code? Not very elegant though. You could stop using gc. Python has reference counting anyway, so the only effect is that you need to manually remove cyclic links between your objects from __del__ methods. It's quite easy with the gc module to dump the number of objects of each type and see which ones aren't being destroyed. |