PARANOIA: add debug to P_SetTarget if references go negative

Prints mobj address, mobj type, thinker function,
reference count and source code line number.
This commit is contained in:
James R 2023-03-20 19:32:11 -07:00
parent 55467d190a
commit 509a023329
4 changed files with 90 additions and 2 deletions

View file

@ -17,6 +17,8 @@
#ifndef __D_THINK__
#define __D_THINK__
#include "doomdef.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -53,6 +55,10 @@ struct thinker_t
// killough 11/98: count of how many other objects reference
// this one using pointers. Used for garbage collection.
INT32 references;
#ifdef PARANOIA
INT32 debug_mobjtype;
#endif
};
#ifdef __cplusplus

View file

@ -11196,6 +11196,11 @@ void P_RemoveMobj(mobj_t *mobj)
P_RemoveThinker((thinker_t *)mobj);
#ifdef PARANOIA
// Saved to avoid being scrambled like below...
mobj->thinker.debug_mobjtype = mobj->type;
#endif
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.
#ifdef SCRAMBLE_REMOVED
// Invalidate mobj_t data to cause crashes if accessed!

View file

@ -42,6 +42,10 @@
#include "k_specialstage.h"
#include "acs/interface.h"
#ifdef PARANOIA
#include "deh_tables.h" // MOBJTYPE_LIST
#endif
tic_t leveltime;
INT32 P_AltFlip(INT32 n, tic_t tics)
@ -228,8 +232,49 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker)
thlist[n].prev = thinker;
thinker->references = 0; // killough 11/98: init reference counter to 0
#ifdef PARANOIA
thinker->debug_mobjtype = MT_NULL;
#endif
}
#ifdef PARANOIA
static const char *MobjTypeName(const mobj_t *mobj)
{
actionf_p1 p1 = mobj->thinker.function.acp1;
if (p1 == (actionf_p1)P_MobjThinker)
{
return MOBJTYPE_LIST[mobj->type];
}
else if (p1 == (actionf_p1)P_RemoveThinkerDelayed)
{
if (mobj->thinker.debug_mobjtype != MT_NULL)
{
return MOBJTYPE_LIST[mobj->thinker.debug_mobjtype];
}
}
return "<Not a mobj>";
}
static const char *MobjThinkerName(const mobj_t *mobj)
{
actionf_p1 p1 = mobj->thinker.function.acp1;
if (p1 == (actionf_p1)P_MobjThinker)
{
return "P_MobjThinker";
}
else if (p1 == (actionf_p1)P_RemoveThinkerDelayed)
{
return "P_RemoveThinkerDelayed";
}
return "<Unknown Thinker>";
}
#endif
//
// killough 11/98:
//
@ -308,11 +353,30 @@ void P_RemoveThinker(thinker_t *thinker)
* references, and delay removal until the count is 0.
*/
mobj_t *P_SetTarget(mobj_t **mop, mobj_t *targ)
mobj_t *P_SetTarget2(mobj_t **mop, mobj_t *targ
#ifdef PARANOIA
, const char *source_file, int source_line
#endif
)
{
if (*mop) // If there was a target already, decrease its refcount
{
(*mop)->thinker.references--;
#ifdef PARANOIA
if ((*mop)->thinker.references < 0)
{
CONS_Printf(
"PARANOIA/P_SetTarget: %p %s %s references=%d, references go negative! (%s:%d)\n",
(void*)*mop,
MobjTypeName(*mop),
MobjThinkerName(*mop),
(*mop)->thinker.references,
source_file,
source_line
);
}
#endif
}
if (targ != NULL) // Set new target and if non-NULL, increase its counter

View file

@ -14,6 +14,8 @@
#ifndef __P_TICK__
#define __P_TICK__
#include "doomdef.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -33,7 +35,18 @@ void P_Ticker(boolean run);
void P_PreTicker(INT32 frames);
void P_DoTeamscrambling(void);
void P_RemoveThinkerDelayed(thinker_t *thinker); //killed
mobj_t *P_SetTarget(mobj_t **mo, mobj_t *target); // killough 11/98
mobj_t *P_SetTarget2(mobj_t **mo, mobj_t *target
#ifdef PARANOIA
, const char *source_file, int source_line
#endif
);
#ifdef PARANOIA
#define P_SetTarget(...) P_SetTarget2(__VA_ARGS__, __FILE__, __LINE__)
#else
#define P_SetTarget P_SetTarget2
#endif
// Negate the value for tics
INT32 P_AltFlip(INT32 value, tic_t tics);