Using TypeSimObjectPtr causing engine crash
by Chris \"Hobbiticus\" Weiland · in Torque Game Engine · 12/14/2003 (3:14 pm) · 1 replies
I recently became aware of the TypeSimObjectPtr type for exposing code variables to script. It seems like a much easier way to do it than having the script pass in a number instead of allowing it to pass in an the object name or the ID of the object. Well, it works fine in theory.
So, I load up my mission, and it's doing fine. The server and client both agree what objects should be effected, and it looks great. However, when I quit the SERVER, it crashes. This could just be included as a "clever" way of stopping the server, but it also happens on map change as well, so I'd rather not :) Also note that this crash does NOT happen on the CLIENT.
Now, to specifics. I'm using a SimObjectPtr<> to hold the object, and when I was stepping through the code, I noticed that when you assign a SimObjectPtr another pointer, it does some funky stuff with notify lists and stuff. So, when you use the "=" operator, it adds an object to the notify list after removing the object it used to point to, or something like that, but that's not what matters. What matters is that this notify list WILL have an element in it if a valid pointer is assigned to it using the "=" operator.
My theory is that since this variable is exposted to the script as a TypeSimObjectPtr, that the console is doing something funky and assigning the variable somehow to bypass the "=" operator, causing the notify list to be empty. Later in the code, if the notify list is empty, then it is null, and it gets dereferenced, causing it to crash. This would also explain why the client does not crash because those variables are being assigned in the unpackUpate function, and I get to play around with ghosting and the like. I am the one that assigns these variables using the "=" operator, therefore they have a non-null notify list on the client. On the server, however, it's up to the console to assign them. If the console just takes a memory offset and changes that memory, then the "=" operator will be bypassed, resulting in the notify list being null.
Here is the code that assigns a console type TypeSimObjectPtr:
Notice that the SimObjectPtr<> variable type is not being used, leading me to believe that this code is wrong. Though, I'm not quite sure how to fix it exactly. I'll post a solution if/when I find one.
So, I load up my mission, and it's doing fine. The server and client both agree what objects should be effected, and it looks great. However, when I quit the SERVER, it crashes. This could just be included as a "clever" way of stopping the server, but it also happens on map change as well, so I'd rather not :) Also note that this crash does NOT happen on the CLIENT.
Now, to specifics. I'm using a SimObjectPtr<> to hold the object, and when I was stepping through the code, I noticed that when you assign a SimObjectPtr another pointer, it does some funky stuff with notify lists and stuff. So, when you use the "=" operator, it adds an object to the notify list after removing the object it used to point to, or something like that, but that's not what matters. What matters is that this notify list WILL have an element in it if a valid pointer is assigned to it using the "=" operator.
My theory is that since this variable is exposted to the script as a TypeSimObjectPtr, that the console is doing something funky and assigning the variable somehow to bypass the "=" operator, causing the notify list to be empty. Later in the code, if the notify list is empty, then it is null, and it gets dereferenced, causing it to crash. This would also explain why the client does not crash because those variables are being assigned in the unpackUpate function, and I get to play around with ghosting and the like. I am the one that assigns these variables using the "=" operator, therefore they have a non-null notify list on the client. On the server, however, it's up to the console to assign them. If the console just takes a memory offset and changes that memory, then the "=" operator will be bypassed, resulting in the notify list being null.
Here is the code that assigns a console type TypeSimObjectPtr:
static void setDataTypeSimObjectPtr(void *dptr, S32 argc, const char **argv, EnumTable *, BitSet32)
{
if(argc == 1)
{
SimObject **obj = (SimObject **)dptr;
*obj = Sim::findObject(argv[0]);
}
else
Con::printf("(TypeSimObjectPtr) Cannot set multiple args to a single S32.");
}Notice that the SimObjectPtr<> variable type is not being used, leading me to believe that this code is wrong. Though, I'm not quite sure how to fix it exactly. I'll post a solution if/when I find one.
Associate Kyle Carter
I see the problem.
A TypeSimObjectPtr has nothing to do with the SimObjectPtr<> template. :)
It just means you have a SimObject * in your class.
Obviously, it would be preferable to use a SimObjectPtr<>, but a bit problematic. Something to fix later, I guess.
So to get the code to work, have a SimObject *. Or make a wrapper function if you want to keep using your SimObjectPtr<>.
(The fix for SimObjectPtr<> would be to make the template classes inherit from a superclass that has a get/set method so that you can call it from the script set function and safely assign things.)