Remove the unused and useless CallStack code

This was never enabled and only implemented for Windows.
This commit is contained in:
dhewg 2011-12-14 01:47:08 +01:00
parent 758a954c0d
commit 41a1122a82
10 changed files with 12 additions and 771 deletions

View file

@ -221,11 +221,6 @@ void idSysLocal::FPU_SetDAZ( bool enable ) {}
bool idSysLocal::LockMemory( void *ptr, int bytes ) { return false; }
bool idSysLocal::UnlockMemory( void *ptr, int bytes ) { return false; }
void idSysLocal::GetCallStack( address_t *callStack, const int callStackSize ) { memset( callStack, 0, callStackSize * sizeof( callStack[0] ) ); }
const char * idSysLocal::GetCallStackStr( const address_t *callStack, const int callStackSize ) { return ""; }
const char * idSysLocal::GetCallStackCurStr( int depth ) { return ""; }
void idSysLocal::ShutdownSymbols( void ) {}
uintptr_t idSysLocal::DLL_Load( const char *dllName ) { return 0; }
void * idSysLocal::DLL_GetProcAddress( uintptr_t dllHandle, const char *procName ) { return NULL; }
void idSysLocal::DLL_Unload( uintptr_t dllHandle ) { }

View file

@ -96,19 +96,6 @@ If you have questions concerning this license or the applicable additional terms
#define ID_ALLOW_TOOLS
#endif
// don't do backtraces in release builds.
// atm, we have no useful way to reconstruct the trace, so let's leave it off
#define ID_BT_STUB
#ifndef ID_BT_STUB
#if defined( __unix__ )
#if defined( _DEBUG )
#define ID_BT_STUB
#endif
#else
#define ID_BT_STUB
#endif
#endif
#ifndef ID_ENFORCE_KEY
# if !defined( ID_DEDICATED ) && !defined( ID_DEMO_BUILD )
# define ID_ENFORCE_KEY 1

View file

@ -305,7 +305,7 @@ void idHeap::Free( void *p ) {
break;
}
default: {
idLib::common->FatalError( "idHeap::Free: invalid memory block (%s)", idLib::sys->GetCallStackCurStr( 4 ) );
idLib::common->FatalError( "idHeap::Free: invalid memory block" );
break;
}
}
@ -384,7 +384,7 @@ dword idHeap::Msize( void *p ) {
return ((idHeap::page_s*)(*((intptr_t *)(((byte *)p) - ALIGN_SIZE( LARGE_HEADER_SIZE )))))->dataSize - ALIGN_SIZE( LARGE_HEADER_SIZE );
}
default: {
idLib::common->FatalError( "idHeap::Msize: invalid memory block (%s)", idLib::sys->GetCallStackCurStr( 4 ) );
idLib::common->FatalError( "idHeap::Msize: invalid memory block" );
return 0;
}
}
@ -1230,15 +1230,12 @@ void Mem_EnableLeakTest( const char *name ) {
#undef Mem_Alloc16
#undef Mem_Free16
#define MAX_CALLSTACK_DEPTH 6
// size of this struct must be a multiple of 16 bytes
typedef struct debugMemory_s {
const char * fileName;
int lineNumber;
int frameNumber;
int size;
address_t callStack[MAX_CALLSTACK_DEPTH];
struct debugMemory_s * prev;
struct debugMemory_s * next;
} debugMemory_t;
@ -1310,15 +1307,13 @@ void Mem_Dump( const char *fileName ) {
}
dump[i] = '\0';
if ( ( b->size >> 10 ) != 0 ) {
fprintf( f, "size: %6d KB: %s, line: %d [%s], call stack: %s\r\n", ( b->size >> 10 ), Mem_CleanupFileName(b->fileName), b->lineNumber, dump, idLib::sys->GetCallStackStr( b->callStack, MAX_CALLSTACK_DEPTH ) );
fprintf( f, "size: %6d KB: %s, line: %d [%s]\r\n", ( b->size >> 10 ), Mem_CleanupFileName(b->fileName), b->lineNumber, dump );
}
else {
fprintf( f, "size: %7d B: %s, line: %d [%s], call stack: %s\r\n", b->size, Mem_CleanupFileName(b->fileName), b->lineNumber, dump, idLib::sys->GetCallStackStr( b->callStack, MAX_CALLSTACK_DEPTH ) );
fprintf( f, "size: %7d B: %s, line: %d [%s], call stack: %s\r\n", b->size, Mem_CleanupFileName(b->fileName), b->lineNumber, dump );
}
}
idLib::sys->ShutdownSymbols();
fprintf( f, "%8d total memory blocks allocated\r\n", numBlocks );
fprintf( f, "%8d KB memory allocated\r\n", ( totalSize >> 10 ) );
@ -1352,7 +1347,6 @@ typedef struct allocInfo_s {
int lineNumber;
int size;
int numAllocs;
address_t callStack[MAX_CALLSTACK_DEPTH];
struct allocInfo_s * next;
} allocInfo_t;
@ -1360,10 +1354,9 @@ typedef enum {
MEMSORT_SIZE,
MEMSORT_LOCATION,
MEMSORT_NUMALLOCS,
MEMSORT_CALLSTACK
} memorySortType_t;
void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int sortCallStack, int numFrames ) {
void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int numFrames ) {
int numBlocks, totalSize, r, j;
debugMemory_t *b;
allocInfo_t *a, *nexta, *allocInfo = NULL, *sortedAllocInfo = NULL, *prevSorted, *nextSorted;
@ -1387,11 +1380,6 @@ void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int sor
if ( a->lineNumber != b->lineNumber ) {
continue;
}
for ( j = 0; j < MAX_CALLSTACK_DEPTH; j++ ) {
if ( a->callStack[j] != b->callStack[j] ) {
break;
}
}
if ( j < MAX_CALLSTACK_DEPTH ) {
continue;
}
@ -1410,9 +1398,6 @@ void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int sor
a->lineNumber = b->lineNumber;
a->size = b->size;
a->numAllocs = 1;
for ( j = 0; j < MAX_CALLSTACK_DEPTH; j++ ) {
a->callStack[j] = b->callStack[j];
}
a->next = allocInfo;
allocInfo = a;
}
@ -1455,16 +1440,6 @@ void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int sor
}
break;
}
// sort on call stack
case MEMSORT_CALLSTACK: {
for ( nextSorted = sortedAllocInfo; nextSorted; nextSorted = nextSorted->next ) {
if ( a->callStack[sortCallStack] < nextSorted->callStack[sortCallStack] ) {
break;
}
prevSorted = nextSorted;
}
break;
}
}
if ( !prevSorted ) {
a->next = sortedAllocInfo;
@ -1484,14 +1459,12 @@ void Mem_DumpCompressed( const char *fileName, memorySortType_t memSort, int sor
// write list to file
for ( a = sortedAllocInfo; a; a = nexta ) {
nexta = a->next;
fprintf( f, "size: %6d KB, allocs: %5d: %s, line: %d, call stack: %s\r\n",
fprintf( f, "size: %6d KB, allocs: %5d: %s, line: %d\r\n",
(a->size >> 10), a->numAllocs, Mem_CleanupFileName(a->fileName),
a->lineNumber, idLib::sys->GetCallStackStr( a->callStack, MAX_CALLSTACK_DEPTH ) );
a->lineNumber );
::free( a );
}
idLib::sys->ShutdownSymbols();
fprintf( f, "%8d total memory blocks allocated\r\n", numBlocks );
fprintf( f, "%8d KB memory allocated\r\n", ( totalSize >> 10 ) );
@ -1507,7 +1480,7 @@ void Mem_DumpCompressed_f( const idCmdArgs &args ) {
int argNum;
const char *arg, *fileName;
memorySortType_t memSort = MEMSORT_LOCATION;
int sortCallStack = 0, numFrames = 0;
int numFrames = 0;
// get cmd-line options
argNum = 1;
@ -1520,15 +1493,6 @@ void Mem_DumpCompressed_f( const idCmdArgs &args ) {
memSort = MEMSORT_LOCATION;
} else if ( idStr::Icmp( arg, "a" ) == 0 ) {
memSort = MEMSORT_NUMALLOCS;
} else if ( idStr::Icmp( arg, "cs1" ) == 0 ) {
memSort = MEMSORT_CALLSTACK;
sortCallStack = 2;
} else if ( idStr::Icmp( arg, "cs2" ) == 0 ) {
memSort = MEMSORT_CALLSTACK;
sortCallStack = 1;
} else if ( idStr::Icmp( arg, "cs3" ) == 0 ) {
memSort = MEMSORT_CALLSTACK;
sortCallStack = 0;
} else if ( arg[0] == 'f' ) {
numFrames = atoi( arg + 1 );
} else {
@ -1552,7 +1516,7 @@ void Mem_DumpCompressed_f( const idCmdArgs &args ) {
} else {
fileName = arg;
}
Mem_DumpCompressed( fileName, memSort, sortCallStack, numFrames );
Mem_DumpCompressed( fileName, memSort, numFrames );
}
/*
@ -1596,7 +1560,6 @@ void *Mem_AllocDebugMemory( const int size, const char *fileName, const int line
mem_debugMemory->prev = m;
}
mem_debugMemory = m;
idLib::sys->GetCallStack( m->callStack, MAX_CALLSTACK_DEPTH );
return ( ( (byte *) p ) + sizeof( debugMemory_t ) );
}
@ -1625,7 +1588,7 @@ void Mem_FreeDebugMemory( void *p, const char *fileName, const int lineNumber, c
m = (debugMemory_t *) ( ( (byte *) p ) - sizeof( debugMemory_t ) );
if ( m->size < 0 ) {
idLib::common->FatalError( "memory freed twice, first from %s, now from %s", idLib::sys->GetCallStackStr( m->callStack, MAX_CALLSTACK_DEPTH ), idLib::sys->GetCallStackCurStr( MAX_CALLSTACK_DEPTH ) );
idLib::common->FatalError( "memory freed twice" );
}
Mem_UpdateFreeStats( m->size );
@ -1644,7 +1607,6 @@ void Mem_FreeDebugMemory( void *p, const char *fileName, const int lineNumber, c
m->lineNumber = lineNumber;
m->frameNumber = idLib::frameNumber;
m->size = -m->size;
idLib::sys->GetCallStack( m->callStack, MAX_CALLSTACK_DEPTH );
if ( align16 ) {
mem_heap->Free16( m );
@ -1748,9 +1710,8 @@ Mem_Shutdown
void Mem_Shutdown( void ) {
if ( mem_leakName[0] != '\0' ) {
Mem_DumpCompressed( va( "%s_leak_size.txt", mem_leakName ), MEMSORT_SIZE, 0, 0 );
Mem_DumpCompressed( va( "%s_leak_location.txt", mem_leakName ), MEMSORT_LOCATION, 0, 0 );
Mem_DumpCompressed( va( "%s_leak_cs1.txt", mem_leakName ), MEMSORT_CALLSTACK, 2, 0 );
Mem_DumpCompressed( va( "%s_leak_size.txt", mem_leakName ), MEMSORT_SIZE, 0 );
Mem_DumpCompressed( va( "%s_leak_location.txt", mem_leakName ), MEMSORT_LOCATION, 0 );
}
idHeap *m = mem_heap;

View file

@ -1,137 +0,0 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
/*
==================
Sys_ShutdownSymbols
==================
*/
void Sys_ShutdownSymbols( void ) {
}
#ifdef ID_BT_STUB
/*
==================
Sys_GetCallStack
==================
*/
void Sys_GetCallStack( address_t *callStack, const int callStackSize ) {
for ( int i = 0; i < callStackSize; i++ ) {
callStack[i] = 0;
}
}
/*
==================
Sys_GetCallStackStr
==================
*/
const char * Sys_GetCallStackStr( const address_t *callStack, const int callStackSize ) {
return "";
}
/*
==================
Sys_GetCallStackStr
==================
*/
const char * Sys_GetCallStackCurStr( int depth ) {
return "";
}
/*
==================
Sys_GetCallStackCurAddressStr
==================
*/
const char * Sys_GetCallStackCurAddressStr( int depth ) {
return "";
}
#else
#include <execinfo.h>
/*
==================
Sys_GetCallStack
==================
*/
void Sys_GetCallStack( address_t *callStack, const int callStackSize ) {
int i;
i = backtrace( (void **)callStack, callStackSize );
while( i < callStackSize ) {
callStack[i++] = 0;
}
}
/*
==================
Sys_GetCallStackStr
==================
*/
const char * Sys_GetCallStackStr( const address_t *callStack, int callStackSize ) {
static char string[MAX_STRING_CHARS*2];
char **strings;
int i;
strings = backtrace_symbols( (void **)callStack, callStackSize );
string[ 0 ] = '\0';
for ( i = 0; i < callStackSize; i++ ) {
idStr::snPrintf( string + strlen( string ), MAX_STRING_CHARS*2 - strlen( string ) - 1, "%s\n", strings[ i ] );
}
free( strings );
return string;
}
/*
==================
Sys_GetCallStackStr
==================
*/
const char * Sys_GetCallStackCurStr( int depth ) {
address_t array[ 32 ];
size_t size;
size = backtrace( (void **)array, Min( 32, depth ) );
return Sys_GetCallStackStr( array, (int)size );
}
/*
==================
Sys_GetCallStackCurAddressStr
==================
*/
const char * Sys_GetCallStackCurAddressStr( int depth ) {
return Sys_GetCallStackCurStr( depth );
}
#endif

View file

@ -106,10 +106,6 @@ static void sig_handler( int signum, siginfo_t *info, void *context ) {
// NOTE: see sigaction man page, could verbose the whole siginfo_t and print human readable si_code
Sys_Printf( "signal caught: %s\nsi_code %d\n", strsignal( signum ), info->si_code );
#ifndef ID_BT_STUB
Sys_Printf( "callstack:\n%s", Sys_GetCallStackCurStr( 30 ) );
#endif
if ( fatalError[ 0 ] ) {
Sys_Printf( "Was in fatal error shutdown: %s\n", fatalError );
}

View file

@ -199,7 +199,6 @@ sys_string = ' \
posix/posix_main.cpp \
posix/posix_signal.cpp \
posix/posix_threads.cpp \
linux/stack.cpp \
linux/main.cpp \
stub/util_stub.cpp'

View file

@ -92,22 +92,6 @@ bool idSysLocal::UnlockMemory( void *ptr, int bytes ) {
return Sys_UnlockMemory( ptr, bytes );
}
void idSysLocal::GetCallStack( address_t *callStack, const int callStackSize ) {
Sys_GetCallStack( callStack, callStackSize );
}
const char * idSysLocal::GetCallStackStr( const address_t *callStack, const int callStackSize ) {
return Sys_GetCallStackStr( callStack, callStackSize );
}
const char * idSysLocal::GetCallStackCurStr( int depth ) {
return Sys_GetCallStackCurStr( depth );
}
void idSysLocal::ShutdownSymbols( void ) {
Sys_ShutdownSymbols();
}
uintptr_t idSysLocal::DLL_Load( const char *dllName ) {
return Sys_DLL_Load( dllName );
}

View file

@ -53,11 +53,6 @@ public:
virtual void FPU_EnableExceptions( int exceptions );
virtual void GetCallStack( address_t *callStack, const int callStackSize );
virtual const char * GetCallStackStr( const address_t *callStack, const int callStackSize );
virtual const char * GetCallStackCurStr( int depth );
virtual void ShutdownSymbols( void );
virtual bool LockMemory( void *ptr, int bytes );
virtual bool UnlockMemory( void *ptr, int bytes );

View file

@ -283,8 +283,6 @@ typedef struct sysMemoryStats_s {
int availExtendedVirtual;
} sysMemoryStats_t;
typedef unsigned long address_t;
template<class type> class idList; // for Sys_ListFiles
@ -370,13 +368,6 @@ bool Sys_UnlockMemory( void *ptr, int bytes );
// set amount of physical work memory
void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes );
// allows retrieving the call stack at execution points
void Sys_GetCallStack( address_t *callStack, const int callStackSize );
const char * Sys_GetCallStackStr( const address_t *callStack, const int callStackSize );
const char * Sys_GetCallStackCurStr( int depth );
const char * Sys_GetCallStackCurAddressStr( int depth );
void Sys_ShutdownSymbols( void );
// DLL loading, the path should be a fully qualified OS path to the DLL file to be loaded
uintptr_t Sys_DLL_Load( const char *dllName );
void * Sys_DLL_GetProcAddress( uintptr_t dllHandle, const char *procName );
@ -605,11 +596,6 @@ public:
virtual bool LockMemory( void *ptr, int bytes ) = 0;
virtual bool UnlockMemory( void *ptr, int bytes ) = 0;
virtual void GetCallStack( address_t *callStack, const int callStackSize ) = 0;
virtual const char * GetCallStackStr( const address_t *callStack, const int callStackSize ) = 0;
virtual const char * GetCallStackCurStr( int depth ) = 0;
virtual void ShutdownSymbols( void ) = 0;
virtual uintptr_t DLL_Load( const char *dllName ) = 0;
virtual void * DLL_GetProcAddress( uintptr_t dllHandle, const char *procName ) = 0;
virtual void DLL_Unload( uintptr_t dllHandle ) = 0;

View file

@ -251,528 +251,3 @@ char *Sys_GetCurrentUser( void ) {
return s_userName;
}
/*
===============================================================================
Call stack
===============================================================================
*/
#define PROLOGUE_SIGNATURE 0x00EC8B55
#include <dbghelp.h>
const int UNDECORATE_FLAGS = UNDNAME_NO_MS_KEYWORDS |
UNDNAME_NO_ACCESS_SPECIFIERS |
UNDNAME_NO_FUNCTION_RETURNS |
UNDNAME_NO_ALLOCATION_MODEL |
UNDNAME_NO_ALLOCATION_LANGUAGE |
UNDNAME_NO_MEMBER_TYPE;
#if defined(_DEBUG) && 1
typedef struct symbol_s {
int address;
char * name;
struct symbol_s * next;
} symbol_t;
typedef struct module_s {
int address;
char * name;
symbol_t * symbols;
struct module_s * next;
} module_t;
module_t *modules;
/*
==================
SkipRestOfLine
==================
*/
void SkipRestOfLine( const char **ptr ) {
while( (**ptr) != '\0' && (**ptr) != '\n' && (**ptr) != '\r' ) {
(*ptr)++;
}
while( (**ptr) == '\n' || (**ptr) == '\r' ) {
(*ptr)++;
}
}
/*
==================
SkipWhiteSpace
==================
*/
void SkipWhiteSpace( const char **ptr ) {
while( (**ptr) == ' ' ) {
(*ptr)++;
}
}
/*
==================
ParseHexNumber
==================
*/
int ParseHexNumber( const char **ptr ) {
int n = 0;
while( (**ptr) >= '0' && (**ptr) <= '9' || (**ptr) >= 'a' && (**ptr) <= 'f' ) {
n <<= 4;
if ( **ptr >= '0' && **ptr <= '9' ) {
n |= ( (**ptr) - '0' );
} else {
n |= 10 + ( (**ptr) - 'a' );
}
(*ptr)++;
}
return n;
}
/*
==================
Sym_Init
==================
*/
void Sym_Init( long addr ) {
TCHAR moduleName[MAX_STRING_CHARS];
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery( (void*)addr, &mbi, sizeof(mbi) );
GetModuleFileName( (HMODULE)mbi.AllocationBase, moduleName, sizeof( moduleName ) );
char *ext = moduleName + strlen( moduleName );
while( ext > moduleName && *ext != '.' ) {
ext--;
}
if ( ext == moduleName ) {
strcat( moduleName, ".map" );
} else {
strcpy( ext, ".map" );
}
module_t *module = (module_t *) malloc( sizeof( module_t ) );
module->name = (char *) malloc( strlen( moduleName ) + 1 );
strcpy( module->name, moduleName );
module->address = (int)mbi.AllocationBase;
module->symbols = NULL;
module->next = modules;
modules = module;
FILE *fp = fopen( moduleName, "rb" );
if ( fp == NULL ) {
return;
}
int pos = ftell( fp );
fseek( fp, 0, SEEK_END );
int length = ftell( fp );
fseek( fp, pos, SEEK_SET );
char *text = (char *) malloc( length+1 );
fread( text, 1, length, fp );
text[length] = '\0';
fclose( fp );
const char *ptr = text;
// skip up to " Address" on a new line
while( *ptr != '\0' ) {
SkipWhiteSpace( &ptr );
if ( idStr::Cmpn( ptr, "Address", 7 ) == 0 ) {
SkipRestOfLine( &ptr );
break;
}
SkipRestOfLine( &ptr );
}
int symbolAddress;
int symbolLength;
char symbolName[MAX_STRING_CHARS];
symbol_t *symbol;
// parse symbols
while( *ptr != '\0' ) {
SkipWhiteSpace( &ptr );
ParseHexNumber( &ptr );
if ( *ptr == ':' ) {
ptr++;
} else {
break;
}
ParseHexNumber( &ptr );
SkipWhiteSpace( &ptr );
// parse symbol name
symbolLength = 0;
while( *ptr != '\0' && *ptr != ' ' ) {
symbolName[symbolLength++] = *ptr++;
if ( symbolLength >= sizeof( symbolName ) - 1 ) {
break;
}
}
symbolName[symbolLength++] = '\0';
SkipWhiteSpace( &ptr );
// parse symbol address
symbolAddress = ParseHexNumber( &ptr );
SkipRestOfLine( &ptr );
symbol = (symbol_t *) malloc( sizeof( symbol_t ) );
symbol->name = (char *) malloc( symbolLength );
strcpy( symbol->name, symbolName );
symbol->address = symbolAddress;
symbol->next = module->symbols;
module->symbols = symbol;
}
free( text );
}
/*
==================
Sym_Shutdown
==================
*/
void Sym_Shutdown( void ) {
module_t *m;
symbol_t *s;
for ( m = modules; m != NULL; m = modules ) {
modules = m->next;
for ( s = m->symbols; s != NULL; s = m->symbols ) {
m->symbols = s->next;
free( s->name );
free( s );
}
free( m->name );
free( m );
}
modules = NULL;
}
/*
==================
Sym_GetFuncInfo
==================
*/
void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName ) {
MEMORY_BASIC_INFORMATION mbi;
module_t *m;
symbol_t *s;
VirtualQuery( (void*)addr, &mbi, sizeof(mbi) );
for ( m = modules; m != NULL; m = m->next ) {
if ( m->address == (int) mbi.AllocationBase ) {
break;
}
}
if ( !m ) {
Sym_Init( addr );
m = modules;
}
for ( s = m->symbols; s != NULL; s = s->next ) {
if ( s->address == addr ) {
char undName[MAX_STRING_CHARS];
if ( UnDecorateSymbolName( s->name, undName, sizeof(undName), UNDECORATE_FLAGS ) ) {
funcName = undName;
} else {
funcName = s->name;
}
for ( int i = 0; i < funcName.Length(); i++ ) {
if ( funcName[i] == '(' ) {
funcName.CapLength( i );
break;
}
}
module = m->name;
return;
}
}
sprintf( funcName, "0x%08x", addr );
module = "";
}
#elif defined(_DEBUG)
DWORD lastAllocationBase = -1;
HANDLE processHandle;
idStr lastModule;
/*
==================
Sym_Init
==================
*/
void Sym_Init( long addr ) {
TCHAR moduleName[MAX_STRING_CHARS];
TCHAR modShortNameBuf[MAX_STRING_CHARS];
MEMORY_BASIC_INFORMATION mbi;
if ( lastAllocationBase != -1 ) {
Sym_Shutdown();
}
VirtualQuery( (void*)addr, &mbi, sizeof(mbi) );
GetModuleFileName( (HMODULE)mbi.AllocationBase, moduleName, sizeof( moduleName ) );
_splitpath( moduleName, NULL, NULL, modShortNameBuf, NULL );
lastModule = modShortNameBuf;
processHandle = GetCurrentProcess();
if ( !SymInitialize( processHandle, NULL, FALSE ) ) {
return;
}
if ( !SymLoadModule( processHandle, NULL, moduleName, NULL, (DWORD)mbi.AllocationBase, 0 ) ) {
SymCleanup( processHandle );
return;
}
SymSetOptions( SymGetOptions() & ~SYMOPT_UNDNAME );
lastAllocationBase = (DWORD) mbi.AllocationBase;
}
/*
==================
Sym_Shutdown
==================
*/
void Sym_Shutdown( void ) {
SymUnloadModule( GetCurrentProcess(), lastAllocationBase );
SymCleanup( GetCurrentProcess() );
lastAllocationBase = -1;
}
/*
==================
Sym_GetFuncInfo
==================
*/
void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName ) {
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery( (void*)addr, &mbi, sizeof(mbi) );
if ( (DWORD) mbi.AllocationBase != lastAllocationBase ) {
Sym_Init( addr );
}
BYTE symbolBuffer[ sizeof(IMAGEHLP_SYMBOL) + MAX_STRING_CHARS ];
PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)&symbolBuffer[0];
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
pSymbol->MaxNameLength = 1023;
pSymbol->Address = 0;
pSymbol->Flags = 0;
pSymbol->Size =0;
DWORD symDisplacement = 0;
if ( SymGetSymFromAddr( processHandle, addr, &symDisplacement, pSymbol ) ) {
// clean up name, throwing away decorations that don't affect uniqueness
char undName[MAX_STRING_CHARS];
if ( UnDecorateSymbolName( pSymbol->Name, undName, sizeof(undName), UNDECORATE_FLAGS ) ) {
funcName = undName;
} else {
funcName = pSymbol->Name;
}
module = lastModule;
}
else {
LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
LocalFree( lpMsgBuf );
// Couldn't retrieve symbol (no debug info?, can't load dbghelp.dll?)
sprintf( funcName, "0x%08x", addr );
module = "";
}
}
#else
/*
==================
Sym_Init
==================
*/
void Sym_Init( long addr ) {
}
/*
==================
Sym_Shutdown
==================
*/
void Sym_Shutdown( void ) {
}
/*
==================
Sym_GetFuncInfo
==================
*/
void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName ) {
module = "";
sprintf( funcName, "0x%08x", addr );
}
#endif
/*
==================
GetFuncAddr
==================
*/
address_t GetFuncAddr( address_t midPtPtr ) {
long temp;
do {
temp = (long)(*(long*)midPtPtr);
if ( (temp&0x00FFFFFF) == PROLOGUE_SIGNATURE ) {
break;
}
midPtPtr--;
} while(true);
return midPtPtr;
}
/*
==================
GetCallerAddr
==================
*/
address_t GetCallerAddr( long _ebp ) {
long midPtPtr;
long res = 0;
__asm {
mov eax, _ebp
mov ecx, [eax] // check for end of stack frames list
test ecx, ecx // check for zero stack frame
jz label
mov eax, [eax+4] // get the ret address
test eax, eax // check for zero return address
jz label
mov midPtPtr, eax
}
res = GetFuncAddr( midPtPtr );
label:
return res;
}
/*
==================
Sys_GetCallStack
use /Oy option
==================
*/
void Sys_GetCallStack( address_t *callStack, const int callStackSize ) {
#if 1 //def _DEBUG
int i;
long m_ebp;
__asm {
mov eax, ebp
mov m_ebp, eax
}
// skip last two functions
m_ebp = *((long*)m_ebp);
m_ebp = *((long*)m_ebp);
// list functions
for ( i = 0; i < callStackSize; i++ ) {
callStack[i] = GetCallerAddr( m_ebp );
if ( callStack[i] == 0 ) {
break;
}
m_ebp = *((long*)m_ebp);
}
#else
int i = 0;
#endif
while( i < callStackSize ) {
callStack[i++] = 0;
}
}
/*
==================
Sys_GetCallStackStr
==================
*/
const char *Sys_GetCallStackStr( const address_t *callStack, const int callStackSize ) {
static char string[MAX_STRING_CHARS*2];
int index, i;
idStr module, funcName;
index = 0;
for ( i = callStackSize-1; i >= 0; i-- ) {
Sym_GetFuncInfo( callStack[i], module, funcName );
index += sprintf( string+index, " -> %s", funcName.c_str() );
}
return string;
}
/*
==================
Sys_GetCallStackCurStr
==================
*/
const char *Sys_GetCallStackCurStr( int depth ) {
address_t *callStack;
callStack = (address_t *) _alloca( depth * sizeof( address_t ) );
Sys_GetCallStack( callStack, depth );
return Sys_GetCallStackStr( callStack, depth );
}
/*
==================
Sys_GetCallStackCurAddressStr
==================
*/
const char *Sys_GetCallStackCurAddressStr( int depth ) {
static char string[MAX_STRING_CHARS*2];
address_t *callStack;
int index, i;
callStack = (address_t *) _alloca( depth * sizeof( address_t ) );
Sys_GetCallStack( callStack, depth );
index = 0;
for ( i = depth-1; i >= 0; i-- ) {
index += sprintf( string+index, " -> 0x%08x", callStack[i] );
}
return string;
}
/*
==================
Sys_ShutdownSymbols
==================
*/
void Sys_ShutdownSymbols( void ) {
Sym_Shutdown();
}