Crash on GetClassID
by Ken Brooks · in Torque Game Engine · 06/17/2004 (6:40 am) · 3 replies
Clearly I will get no more work out of TNL until Mark gets back. I wish this thing didn't break under me every time I put any weight on it! But meanwhile, to document in detail:
TNLNetClass.h shows an example scenario, SimpleMessageEvent.
I adopted it, and here is the relevant portion of my code:
void CMEventConnection::onConnectionEstablished()
{
char buf[256];
bool isClient;
Parent::onConnectionEstablished();
isClient = isInitiator();
if(isClient) {
sprintf(buf, "Connected to server at address %s.", getNetAddressString()); // this happens
SimpleMessageEvent e("I'm alive!");
postNetEvent(&e);
}
. . .
}
void main(...) {
. . .
while(!gQuit)
{
theNetInterface->checkIncomingPackets();
theNetInterface->processConnections();
Platform::sleep(1);
}
}
Now, once that SimpleMessageEvent is posted, I get a bus error crash under ProcessConnections. Chasing it down with the debugger,
#0 0x000ac8e8 in TNL::NetClassRep::getClassId(TNL::NetClassGroup) const at tnlNetBase.h:279
#1 0x000ac3d4 in TNL::Object::getClassId(TNL::NetClassGroup) const at tnlNetBase.h:447
#2 0x0002d42c in TNL::EventConnection::writePacket(TNL::BitStream*, TNL::NetConnection::PacketNotify*) at eventConnection.cpp:258
#3 0x0002a3c0 in TNL::NetConnection::writeRawPacket(TNL::BitStream*, TNL::NetConnection::NetPacketType) at netConnection.cpp:214
#4 0x0002b930 in TNL::NetConnection::checkPacketSend(bool, unsigned) at netConnection.cpp:666
#5 0x000258c4 in TNL::NetInterface::processConnections() at netInterface.cpp:320
#6 0x00008de8 in main at EventLevel.cpp:92
In particular, it does a getClassId on a seemingly well-behaved object, address bffff060:
from tnlNetBase.h:
inline U32 Object::getClassId(NetClassGroup classGroup) const
{
TNLAssert(getClassRep() != NULL,
"Cannot get class id from non-declared dynamic class");
return getClassRep()->getClassId(classGroup);
}
However, getClassRep gets here - having seemingly leaped right over the TNLAssert and ignored it - and returns NULL. (I cannot set a breakpoint on the TNLAssert) We then call getClassId on a NULL object, and crash.
from NetBase.cpp:
//--------------------------------------
NetClassRep* Object::getClassRep() const
{
return NULL;
}
Basically, it is doing a getClassRep on a NetEvent object, presumably my SimpleMessageEvent;
this object is telling me that it has not had:
DECLARE_CONOBJECT(SimpleMessageEvent);
and
IMPLEMENT_CONOBJECT(SimpleMessageEvent);
But adding them doesn't help! What else is there to declare???
And I can assure you that both
TNL_DECLARE_CLASS(SimpleMessageEvent);
and
TNL_IMPLEMENT_NETEVENT(SimpleMessageEvent, NetClassGroupGameMask, 0);
were done in their appropriate places.
TNLNetClass.h shows an example scenario, SimpleMessageEvent.
I adopted it, and here is the relevant portion of my code:
void CMEventConnection::onConnectionEstablished()
{
char buf[256];
bool isClient;
Parent::onConnectionEstablished();
isClient = isInitiator();
if(isClient) {
sprintf(buf, "Connected to server at address %s.", getNetAddressString()); // this happens
SimpleMessageEvent e("I'm alive!");
postNetEvent(&e);
}
. . .
}
void main(...) {
. . .
while(!gQuit)
{
theNetInterface->checkIncomingPackets();
theNetInterface->processConnections();
Platform::sleep(1);
}
}
Now, once that SimpleMessageEvent is posted, I get a bus error crash under ProcessConnections. Chasing it down with the debugger,
#0 0x000ac8e8 in TNL::NetClassRep::getClassId(TNL::NetClassGroup) const at tnlNetBase.h:279
#1 0x000ac3d4 in TNL::Object::getClassId(TNL::NetClassGroup) const at tnlNetBase.h:447
#2 0x0002d42c in TNL::EventConnection::writePacket(TNL::BitStream*, TNL::NetConnection::PacketNotify*) at eventConnection.cpp:258
#3 0x0002a3c0 in TNL::NetConnection::writeRawPacket(TNL::BitStream*, TNL::NetConnection::NetPacketType) at netConnection.cpp:214
#4 0x0002b930 in TNL::NetConnection::checkPacketSend(bool, unsigned) at netConnection.cpp:666
#5 0x000258c4 in TNL::NetInterface::processConnections() at netInterface.cpp:320
#6 0x00008de8 in main at EventLevel.cpp:92
In particular, it does a getClassId on a seemingly well-behaved object, address bffff060:
from tnlNetBase.h:
inline U32 Object::getClassId(NetClassGroup classGroup) const
{
TNLAssert(getClassRep() != NULL,
"Cannot get class id from non-declared dynamic class");
return getClassRep()->getClassId(classGroup);
}
However, getClassRep gets here - having seemingly leaped right over the TNLAssert and ignored it - and returns NULL. (I cannot set a breakpoint on the TNLAssert) We then call getClassId on a NULL object, and crash.
from NetBase.cpp:
//--------------------------------------
NetClassRep* Object::getClassRep() const
{
return NULL;
}
Basically, it is doing a getClassRep on a NetEvent object, presumably my SimpleMessageEvent;
this object is telling me that it has not had:
DECLARE_CONOBJECT(SimpleMessageEvent);
and
IMPLEMENT_CONOBJECT(SimpleMessageEvent);
But adding them doesn't help! What else is there to declare???
And I can assure you that both
TNL_DECLARE_CLASS(SimpleMessageEvent);
and
TNL_IMPLEMENT_NETEVENT(SimpleMessageEvent, NetClassGroupGameMask, 0);
were done in their appropriate places.
About the author
Associate Kyle Carter
Can you show me where you've put your macros?
Assert macros don't get compiled in unless you're running with the right debug asserts.