[ODE] a bug in dBodyDestroy

David McClurg dmcclurg at pandemicstudios.com.au
Thu Feb 20 16:38:01 2003


Eeek!!! nice catch. I think I've seen this too but couldn't quite figure it out.  I'm using multiple geoms per body as well.  Do you have a patch for Russ to commit?  Would this work...

void dBodyDestroy (dxBody *b)
{
  dAASSERT (b);

  // all geoms that link to this body must be notified that the body is about
  // to disappear. 
  while (b->geom) {
    dGeomSetBody (b->geom,0);
    // note: dGeomSetBody() will remove the geom from our list!
  }

  <snip>
}

Thanks!

-----Original Message-----
From: slipch [mailto:slipch@gsc-game.kiev.ua]
Sent: Friday, 21 February 2003 5:39 AM
To: ODE@q12.org
Subject: [ODE] a bug in dBodyDestroy


Hello ODE,

If the "body" has more than one "geometry" attached to it then
dBodyDestroy intends to remove the body from all attached
"geometries". For this purpose dBodyDestroy has code


  for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) {
    dGeomSetBody (geom,0);
  }  

But   dGeomSetBody calls g->bodyRemove().

void dGeomSetBody (dxGeom *g, dxBody *b)
{
  ........................
  .......................
  if (b) {
           ...............
           ...............
  }
  else {
    if (g->body) {
     .......................
     .......................
      g->bodyRemove();
    }
  }
}

In its turn  bodyRemove() sets body_next to zero.

void dxGeom::bodyRemove()
{
  if (body) {
     .....................
     ......................
    body_next = 0;
  }
}

 and   dGeomGetBodyNext (geom) always return zero after first
 iteration.

dxGeom *dGeomGetBodyNext (dxGeom *geom)
{
  return geom->body_next;
} 

So we will never iterate through all "geometries" attached to this
body.
It may lead to access violation when you try to delete "geometry"
with "body" which was deleted but not set to zero because ~dxGeom() again calls bodyRemove().

-- 
Best regards,
 Konstantin Slipchenko                          mailto:slipch@gsc-game.kiev.ua