clear tmthing at tic end (#635)

@rfomin Hopefully this fixes the rare segmentation faults you
experienced after the z_zone rewrite. At least it fixes the one
use-after-free issue I have found with valgrind before.

Fixes #636
This commit is contained in:
Fabian Greffrath 2022-07-02 10:59:03 +02:00 committed by GitHub
parent 985c9dbc04
commit 5fbf91cb17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 0 deletions

View File

@ -1922,12 +1922,14 @@ static void G_DoLoadGame(void)
basetic = gametic - (int) *save_p++;
// dearchive all the modifications
P_MapStart();
P_UnArchivePlayers();
P_UnArchiveWorld();
P_UnArchiveThinkers();
P_UnArchiveSpecials();
P_UnArchiveRNG(); // killough 1/18/98: load RNG information
P_UnArchiveMap(); // killough 1/22/98: load automap information
P_MapEnd();
if (*save_p != 0xe6)
I_Error ("Bad savegame");
@ -2011,9 +2013,11 @@ void G_Ticker(void)
int i;
// do player reborns if needed
P_MapStart();
for (i=0 ; i<MAXPLAYERS ; i++)
if (playeringame[i] && players[i].playerstate == PST_REBORN)
G_DoReborn (i);
P_MapEnd();
// do things to change the game state
while (gameaction != ga_nothing)

View File

@ -31,6 +31,7 @@
#include "g_game.h"
#include "r_data.h"
#include "p_inter.h"
#include "p_map.h"
#include "m_cheat.h"
#include "m_argv.h"
#include "s_sound.h"
@ -352,6 +353,7 @@ static void cheat_god()
mapthing_t mt = {0};
extern void P_SpawnPlayer (mapthing_t* mthing);
P_MapStart();
mt.x = plyr->mo->x >> FRACBITS;
mt.y = plyr->mo->y >> FRACBITS;
mt.angle = (plyr->mo->angle + ANG45/2)*(uint64_t)45/ANG45;
@ -362,6 +364,7 @@ static void cheat_god()
an = plyr->mo->angle >> ANGLETOFINESHIFT;
P_SpawnMobj(plyr->mo->x+20*finecosine[an], plyr->mo->y+20*finesine[an], plyr->mo->z, MT_TFOG);
S_StartSound(plyr->mo, sfx_slop);
P_MapEnd();
}
plyr->cheats ^= CF_GODMODE;
@ -620,6 +623,7 @@ static void cheat_massacre() // jff 2/01/98 kill all monsters
extern void A_PainDie(mobj_t *);
// killough 7/20/98: kill friendly monsters only if no others to kill
int mask = MF_FRIEND;
P_MapStart();
do
while ((currentthinker=currentthinker->next)!=&thinkercap)
if (currentthinker->function == P_MobjThinker &&
@ -639,6 +643,7 @@ static void cheat_massacre() // jff 2/01/98 kill all monsters
}
}
while (!killcount && mask ? mask=0, 1 : 0); // killough 7/20/98
P_MapEnd();
// killough 3/22/98: make more intelligent about plural
// Ty 03/27/98 - string(s) *not* externalized
doomprintf("%d Monster%s Killed", killcount, killcount==1 ? "" : "s");

View File

@ -2266,6 +2266,23 @@ void P_CreateSecNodeList(mobj_t *thing,fixed_t x,fixed_t y)
}
}
/* cphipps 2004/08/30 -
* Must clear tmthing at tic end, as it might contain a pointer to a
* removed thinker, or the level might have ended/been ended and we
* clear the objects it was pointing too. Hopefully we don't need to
* carry this between tics for sync. */
void P_MapStart(void)
{
if (tmthing)
I_Error("P_MapStart: tmthing set!");
}
void P_MapEnd(void)
{
tmthing = NULL;
}
// [FG] SPECHITS overflow emulation from Chocolate Doom / PrBoom+
static void SpechitOverrun(line_t *ld)

View File

@ -71,6 +71,9 @@ int P_GetMoveFactor(const mobj_t *mo, int *friction); // killough 8/28/98
int P_GetFriction(const mobj_t *mo, int *factor); // killough 8/28/98
void P_ApplyTorque(mobj_t *mo); // killough 9/12/98
void P_MapStart(void);
void P_MapEnd(void);
// If "floatok" true, move would be ok if within "tmfloorz - tmceilingz".
extern boolean floatok;
extern boolean felldown; // killough 11/98: indicates object pushed off ledge

View File

@ -1600,6 +1600,7 @@ void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
bodyqueslot = 0;
deathmatch_p = deathmatchstarts;
P_MapStart();
P_LoadThings(lumpnum+ML_THINGS);
// if deathmatch, randomly spawn the active players
@ -1626,6 +1627,7 @@ void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
// set up world state
P_SpawnSpecials();
P_MapEnd();
// preload graphics
if (precache)

View File

@ -30,6 +30,7 @@
#include "p_user.h"
#include "p_spec.h"
#include "p_tick.h"
#include "p_map.h"
#include "s_musinfo.h" // [crispy] T_MAPMusic()
int leveltime;
@ -263,13 +264,18 @@ void P_Ticker (void)
players[consoleplayer].viewz != 1))
return;
P_MapStart();
if (gamestate == GS_LEVEL)
{
for (i=0; i<MAXPLAYERS; i++)
if (playeringame[i])
P_PlayerThink(&players[i]);
}
P_RunThinkers();
P_UpdateSpecials();
P_RespawnSpecials();
P_MapEnd();
leveltime++; // for par times
}