Game Development Community

Possibly nasty bug in TSShapeConstructor::addSequence() - LOGGED

by Manoel Neto · in Torque 3D Professional · 05/06/2010 (1:48 pm) · 7 replies

I don't know why this doesn't cause problems more often, since I just caught it by chance. In the TSShapeConstructor addSequence console method body, there's this:

if (object->mShape->addSequence(fileBuf, seqName, destName, startFrame, endFrame, &totalFrames))
{
   ADD_TO_CHANGE_SET();

ADD_TO_CHANGE_SET() is a macro that defines this:
object->addToChangeSet(argv[0], argc-2, argv+2);

My game was suddenly fatally asserting after adding some animations due to argv[0] being NULL and being passed to dStrcmp() somewhere inside addToChangeSet(), which doesn't make sense, since argv[0] is the method's name and isn't supposed to be NULL nor change like this. A data breakpoint revelaed that it was modified in StringStack::getArgcArgv() *during* the executing of mShape->addSequence(). To be specific, it happens when the resource manager uses eval() to call exec() on the shape's .CS file automatically.

It became obvious that the argv array is shared and calling console functions/methods within the body of another console function/method can override it, making them not safe to be read afterwards.

#1
05/07/2010 (12:29 am)
Yes, calling multiple commands between C++ and TorqueScript (for example, I add a TorqueScript function that called a C++ function that in turn called another TorqueScript function for validation of certain parameters) will crash or get corrupted parameters because this type of sequence call corrupt the call stack.

I hoped it get fixed with T3D.

(Tests done in TGE 1.52).
#2
05/07/2010 (5:30 am)
I got around this specific case by storing argv[0] in a temporary variable then restoring it before calling ADD_TO_CHANGE_SET().
#3
05/07/2010 (8:24 pm)
Nice catch, Manoel. Will be fixed in next beta.
#4
05/27/2010 (12:04 pm)
Redacted.
#5
05/27/2010 (1:33 pm)
@Joseph: the problem isn't ADD_TO_CHANGE_SET(). It's the line right above it:

if (object->mShape->addSequence(fileBuf, seqName, destName, startFrame, endFrame, &totalFrames))

If you're adding a sequence from a different DAE/DTS file, then that file will be loaded so sequences can be read from it. The resource manager automatically executes any <model file name>.cs scripts it find at the same folder as the DAE/DTS being loaded. So, calling mShape->addSequence() may execute scripts, which may mess up a argv's contents, making the argv[0] passed into ADD_TO_CHANGE_SET() no longer valid.
#6
05/27/2010 (4:04 pm)
@Manoel: Much better explanation, I see now where the error is originating from, I traced a little too far down.


Seems that ConsoleMethod/ConsoleFunction would allow for unshared memory to avoid this issue of cross contamination, because I can see this being an easily overlooked and potentially other bugs being introduced that won't even raise assertions just feed false values that you could be spending days debugging if you even notice.
#7
05/28/2010 (12:33 pm)
bug logged key: TQA-157