diff options
Diffstat (limited to 'mp/src/game/client/cliententitylist.cpp')
| -rw-r--r-- | mp/src/game/client/cliententitylist.cpp | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/mp/src/game/client/cliententitylist.cpp b/mp/src/game/client/cliententitylist.cpp index 294d4ff1..2f983e62 100644 --- a/mp/src/game/client/cliententitylist.cpp +++ b/mp/src/game/client/cliententitylist.cpp @@ -354,6 +354,67 @@ void CClientEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle ) } +#if defined( STAGING_ONLY ) + +// Defined in tier1 / interface.cpp for Windows and native for POSIX platforms. +extern "C" int backtrace( void **buffer, int size ); + +static struct +{ + int entnum; + float time; + C_BaseEntity *pBaseEntity; + void *backtrace_addrs[ 16 ]; +} g_RemoveEntityBacktraces[ 1024 ]; +static uint32 g_RemoveEntityBacktracesIndex = 0; + +static void OnRemoveEntityBacktraceHook( int entnum, C_BaseEntity *pBaseEntity ) +{ + int index = g_RemoveEntityBacktracesIndex++; + if ( g_RemoveEntityBacktracesIndex >= ARRAYSIZE( g_RemoveEntityBacktraces ) ) + g_RemoveEntityBacktracesIndex = 0; + + g_RemoveEntityBacktraces[ index ].entnum = entnum; + g_RemoveEntityBacktraces[ index ].time = gpGlobals->curtime; + g_RemoveEntityBacktraces[ index ].pBaseEntity = pBaseEntity; + + memset( g_RemoveEntityBacktraces[ index ].backtrace_addrs, 0, sizeof( g_RemoveEntityBacktraces[ index ].backtrace_addrs ) ); + backtrace( g_RemoveEntityBacktraces[ index ].backtrace_addrs, ARRAYSIZE( g_RemoveEntityBacktraces[ index ].backtrace_addrs ) ); +} + +// Should help us track down CL_PreserveExistingEntity Host_Error() issues: +// 1. Set cl_removeentity_backtrace_capture to 1. +// 2. When error hits, run "cl_removeentity_backtrace_dump [entnum]". +// 3. In debugger, track down what functions the spewed addresses refer to. +static ConVar cl_removeentity_backtrace_capture( "cl_removeentity_backtrace_capture", "0", 0, + "For debugging. Capture backtraces for CClientEntityList::OnRemoveEntity calls." ); + +CON_COMMAND( cl_removeentity_backtrace_dump, "Dump backtraces for client OnRemoveEntity calls." ) +{ + if ( !cl_removeentity_backtrace_capture.GetBool() ) + { + Msg( "cl_removeentity_backtrace_dump error: cl_removeentity_backtrace_capture not enabled. Backtraces not captured.\n" ); + return; + } + + int entnum = ( args.ArgC() >= 2 ) ? atoi( args[ 1 ] ) : -1; + + for ( int i = 0; i < ARRAYSIZE( g_RemoveEntityBacktraces ); i++ ) + { + if ( g_RemoveEntityBacktraces[ i ].time && + ( entnum == -1 || g_RemoveEntityBacktraces[ i ].entnum == entnum ) ) + { + Msg( "%d: time:%.2f pBaseEntity:%p\n", g_RemoveEntityBacktraces[i].entnum, + g_RemoveEntityBacktraces[ i ].time, g_RemoveEntityBacktraces[ i ].pBaseEntity ); + for ( int j = 0; j < ARRAYSIZE( g_RemoveEntityBacktraces[ i ].backtrace_addrs ); j++ ) + { + Msg( " %p\n", g_RemoveEntityBacktraces[ i ].backtrace_addrs[ j ] ); + } + } + } +} + +#endif // STAGING_ONLY void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle ) { @@ -380,6 +441,13 @@ void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity(); +#if defined( STAGING_ONLY ) + if ( cl_removeentity_backtrace_capture.GetBool() ) + { + OnRemoveEntityBacktraceHook( entnum, pBaseEntity ); + } +#endif // STAGING_ONLY + if ( pBaseEntity ) { if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE ) @@ -502,4 +570,4 @@ C_BaseEntity* C_BaseEntityIterator::Next() } return NULL; -}
\ No newline at end of file +} |