I have nearly reached my own end with this bug.  I can not solve it for the
life of me. Every so often my game freezes. It sort of hangs, and the server
has to be restarted. If I compile a debug version and run the server in the
debugger and wait for a crash, I will get an assertion error
_BLOCK_TYPE_IS_VALID_(pHead->nBlockUse). So I google searched that error and I
found a few causes which make some sense. One of them was running outside the
bounds of an array. I assume that�s a global array which is in the heap, not
the stack.  I also read that the error can occur when dynamically allocated
memory gets deleted twice. This would seem the more likely case in my
situation.
However the weird part is the crash only occurs �sometimes�. I have tried for 3
weeks to repeat it or look for a patterns with very little luck. I have managed
to isolate the crash to one particular function which deletes a bunch of
dynamically allocated memory. However, like I said, most of the time, it works.
Some times it crashes. About 1/20 crashes.
        The code where the crash occurs is very simple. I am simply deleting a
linked list I created previously. In no place in my code were the pointers to
my memory changed, nor were any new pointers assigned to the same block of
memory via = assignment operator. It�s a cut and dry case and this is why I�m
dumbfounded. I have gone to the extreme of making a file dump and outputting
commands during the execution of the game. This is how I found out where the
crash occurred. The last output was entering this function.  So it crashes
somewhere in that function. I�ll just go ahead and post the function and see if
anyone else can make sense of it.

What I have done is redone the spawn code. I load all the spawn points from a
map into a list and the get a random number from 0-X where X is the amount of
spawn points -1 and return that spawn point when someone needs a random one.
This speeds up spawning a little but its real purpose was to solve another
problem for teamplay spawns. It made it a lot easier to get a random spawn
point in which case I have 0-x lists of spawns and each list represents a team.
Being that teamspawns are all the same entity with just a different key value,
this allows us to use team maps with deathmatch with only having to deal with
one spawn entity. Anyway� without going into too much detail about that here is
the code.

//Header file

class SpawnNode
{
        public:
        SpawnNode();
        CBaseDMStart* m_pSpawnPoint;
        SpawnNode* m_pNext;
};

class SpawnPointsDM
{
protected:
        int m_nSpawnPoints;
public:
        SpawnNode* m_pHead;

        SpawnPointsDM();
        ~SpawnPointsDM();
        void ClearList();
        void CreateSpawnList();
        edict_t* FindRandomSpawnPoint(CBasePlayer* pPlayer      );

};

//Source file

//===================
//SpawnNode
//===================

SpawnNode::SpawnNode()
{
        m_pNext=NULL;
        m_pSpawnPoint=NULL;
}


//===================
//SpawnPointsDM
//===================

SpawnPointsDM::SpawnPointsDM()
{
        m_nSpawnPoints = 0;
        m_pHead = NULL;
}

void SpawnPointsDM::CreateSpawnList()
{
#ifdef HLE_DEBUG // DEBUG FILE DUMP ==============

                debug_file.OpenFile();
                debug_file << "SpawnPointsDM::CreateSpawnList(); Start\n";
                debug_file.CloseFile();

#endif  // END FILE DUMP =========================

        ClearList();

        SpawnNode* pNode = NULL;
        SpawnNode *pParent=NULL;
        CBaseEntity *pSpot=NULL;


        pSpot = UTIL_FindEntityByClassname( NULL, "info_player_deathmatch");
        while(pSpot)
        {
                pNode = new SpawnNode();
                pNode->m_pSpawnPoint = (CBaseDMStart*)pSpot;
                if(!pParent)
                        m_pHead = pNode;
                else
                        pParent->m_pNext = pNode;

                pParent = pNode;
                m_nSpawnPoints++;

                pSpot = UTIL_FindEntityByClassname(
pSpot, "info_player_deathmatch" );
        }
#ifdef HLE_DEBUG // DEBUG FILE DUMP ==============

                debug_file.OpenFile();
                debug_file << "SpawnPointsDM::CreateSpawnList(); End\n";
                debug_file.CloseFile();

#endif  // END FILE DUMP =========================

}

extern BOOL IsSpawnPointValid( CBaseEntity *pPlayer, CBaseEntity *pSpot );

edict_t* SpawnPointsDM::FindRandomSpawnPoint(CBasePlayer* pPlayer)
{
        if(m_nSpawnPoints == 0)
                return NULL;

        int spots = RANDOM_LONG(0,m_nSpawnPoints-1);
        SpawnNode* pSpot = m_pHead;
        //
        // get a random spot
        //
        for (int k = 0; k < spots; k++)
        {
                pSpot = pSpot->m_pNext;
        }
        // now check this spot to make sure no one is around, else loop thu
until we find an open spot
        // else clearn out an area terminater style and spawn the player

        for(int i = 0; i < m_nSpawnPoints; i++)
        {
                if(pSpot->m_pSpawnPoint)
                {
                        if(IsSpawnPointValid( pPlayer, pSpot->m_pSpawnPoint) )
                                return pSpot->m_pSpawnPoint->edict();
                }
                if(!pSpot->m_pNext)
                        pSpot->m_pNext = m_pHead;
                else
                        pSpot = pSpot->m_pNext;
        }

        CBaseEntity *ent = NULL;
        // clear the area for the spawn
        while ( (ent = UTIL_FindEntityInSphere( ent, pSpot->m_pSpawnPoint->pev-
>origin, 128 )) != NULL )
        {
                // if ent is a client, kill em (unless they are ourselves)
                if ( ent->IsPlayer() && !(ent->edict() == pPlayer->edict()) )
                        ent->TakeDamage( VARS(INDEXENT(0)), VARS(INDEXENT(0)),
300, DMG_GENERIC );
        }
        return pSpot->m_pSpawnPoint->edict();
};

SpawnPointsDM::~SpawnPointsDM()
{
        ClearList();

#ifdef HLE_DEBUG // DEBUG FILE DUMP ==============

                debug_file.OpenFile();
                debug_file << "SpawnPointsDM::~SpawnPointsDM()\n";
                debug_file.CloseFile();

#endif  // END FILE DUMP =========================
}

void SpawnPointsDM::ClearList()
{
#ifdef HLE_DEBUG // DEBUG FILE DUMP ==============

                debug_file.OpenFile();
                debug_file << "SpawnPointsDM::ClearList(); Start\n";
                debug_file.CloseFile();

#endif  // END FILE DUMP =========================

        SpawnNode* pNode = m_pHead;
        while(pNode)
        {
                m_pHead = pNode->m_pNext;
                delete pNode;
                pNode = m_pHead;
        }
        m_pHead = NULL;
        m_nSpawnPoints = 0;

#ifdef HLE_DEBUG // DEBUG FILE DUMP ==============

                debug_file.OpenFile();
                debug_file << "SpawnPointsDM::ClearList(); End\n";
                debug_file.CloseFile();

#endif  // END FILE DUMP =========================

}



I must apologies for the length of the code, you can pretty much ignore #endif
statements. Those are the file dump line of code. The game crashes with those
in or out. They just tell me where the last part of execution was.  debug_file
is not a fstream ,it�s a custom class I made which has a time stamp when it
outputs, that�s why I looks a lil different.  The dump file helps me figure out
what was going on int he server before it crashed, I dont run the servers, they
are in other states so its not like they can all be run in a debugger.

When the file crashes the last line is always: �SpawnPointsDM::ClearList();
Start�

The crash always occurs in ClearList();

ClearList gets called from the destructor of of  SpawnPointsDM. There is a
SpawnPointsDM m_spawnpoints; object inside my game rules class. So when I
delete gpGameRules, the destructor for SpawnPointsDM is called which then calls
ClearList();  Like I said, it works 19 out of 20 times, and that�s just an
average. Sometimes its gone for over 100 times (100 level changes ) before
crashing, but it always crashes there.  It seems to be independend of the map,
but seems to occur more often when more people are in the server (I can�t prove
its directly related)

I have another classed called SpawnPointsTeam, which gets used in teamplay
modes opposed to this class. That class is nearly identical to this one expect
it has more then 1 linked list. It has a linked list for each team, and then it
finds a random spawn from the list that matches a players team. The ClearList
() code is nearly identical and the crash also occurs in that ClearList ()
function too, at random times.  I would post that code too, but I think this
email is long enough, lol.

When it does not crash the code works perfectly, the spawns are nice and random
so I really don�t understand this. � the problem is I can�t really debug it
because I have no way of knowing when a crash will occur, so I could just step
into that function each time a level changes, but I might have to do that 100
times with 2 or 3 people in the server in which they will disconnect if I don�t
step thu fast enough and resume. That�s just crazy.  I need other suggestions
please!  This is the final bug in a long list of bugs for my mod. After I solve
this, I will able to release it because we have finished all of our programming
and art tasks, its very exciting, 2+ years in the making!





_______________________________________________
To unsubscribe, edit your list preferences, or view the list archives, please visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders

Reply via email to