Game Development Community

TSMesh::render() & TSMesh::smObject accessing deleted memory

by Robert Rose · in Torque Game Engine Advanced · 01/27/2008 (1:58 am) · 3 replies

I've got a random crash that I finally caught in a journal last night and have been tracking down the cause. The crash is a __non_rtti_object exception but it looks like that's just a symptom, after investigation I discovered that what was throwing the exception was an access to TSMesh::smObject in TSMesh::render().

TSMesh::smObject appears to be referencing deleted memory, it's set completely to 0xcececece. To try and catch the problem earlier I set a trap in operator delete to check to see if the deleted memory range contained TSMesh::smObject. Sure enough, right before the crash Torque deletes the memory referenced by TSMesh::smObject.

The deleted object is an AIPlayer that has just died and is in the process of getting cleaned up. The deletion comes from a network message; the actual delete is done in SimObject::deleteObject().

Moments later, in the same frame, SceneGraph::treeTraverseVisit() gets called from WaterBlock::updateReflection() and the second object to be rendered is a Projectile. Now here's where my understanding of TSMesh::smObject breaks down--Projectile::prepBatchRender() results in a call to TSMesh::render() which then refers to TSMesh::smObject, which is set to the AIPlayer that got deleted. I don't know how smObject is intended to be used, but shouldn't it be the projectile?

Any ideas? This bug is causing me to lose sleep. :)

#1
01/27/2008 (2:04 am)
Well. Hmm. I may have fixed it. If I call TSMesh::setObject() in Projectile::prepBatchRender() it no longer crashes. (At least my journal no longer crashes..)

void Projectile::prepBatchRender(SceneState* state)
{
   // DAW: New code for TSE
   MatrixF proj = GFX->getProjectionMatrix();

   RectI viewport = GFX->getViewport();
   state->setupObjectProjection(this);

   // hack until new scenegraph in place
   MatrixF world = GFX->getWorldMatrix();
   TSMesh::setCamTrans( world );
   TSMesh::setSceneState( state );
   TSMesh::setObject(this);   // <--- here's what I added
   ...

Can someone with some expertise here please comment on this? :-) Is this a safe thing to be doing? I'm probably still going to lose sleep over this. :-)
#2
01/28/2008 (8:47 am)
Looks like you found a bug, and fixed it. Good fix!
#3
02/06/2008 (5:06 am)
Yes, that makes sense. smObject needs to be set in order for this line to work correctly in TSMesh Render, used to calculate what looks like z sorting. TSMesh::render uses the smObject global, so it better be valid or NULL before the render happens!

coreRI->calcSortPoint( smObject, smSceneState->getCameraPosition() );

There are several more instances of smObject around the code, set with that TSMesh::setObject line. Never seen that particular crash but I did find some other cases where the smObject wasn't valid and needed to be set. I think was in guiObjectView, but can't tell now.