openmohaa/code/globalcpp/dbgheap.cpp
2016-03-27 11:49:47 +02:00

226 lines
4 KiB
C++

/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA 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 2 of the License,
or (at your option) any later version.
OpenMoHAA 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 OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// dbgheap.cpp: Heap Debugger.
#include <glb_local.h>
#include <dbgheap.h>
DbgHeap m_Heap;
refptr_t *DbgHeap::hashTable[ DBG_HEAP_HASHSIZE ];
#ifdef WIN32
extern "C" {
typedef struct _SYMBOL_INFO {
unsigned long SizeOfStruct;
unsigned long TypeIndex;
unsigned __int64 Reserved[ 2 ];
unsigned long Index;
unsigned long Size;
unsigned __int64 ModBase;
unsigned long Flags;
unsigned __int64 Value;
unsigned __int64 Address;
unsigned long Register;
unsigned long Scope;
unsigned long Tag;
unsigned long NameLen;
unsigned long MaxNameLen;
char Name[ 1 ];
} SYMBOL_INFO, *PSYMBOL_INFO;
unsigned short __stdcall RtlCaptureStackBackTrace
(
unsigned long FramesToSkip,
unsigned long FramesToCapture,
void *BackTrace,
unsigned long *BackTraceHash
);
void * __stdcall GetCurrentProcess
(
void
);
unsigned int __stdcall SymInitialize
(
void *hProcess,
const char *UserSearchPath,
int fInvadeProcess
);
unsigned int __stdcall SymFromAddr
(
void *hProcess,
unsigned long long Address,
unsigned long long *Displacement,
PSYMBOL_INFO Symbol
);
}
#endif
DbgHeap::DbgHeap()
{
}
DbgHeap::~DbgHeap()
{
/*
refptr_t *rootptr;
refptr_t *ref;
refptr_t *next;
for( int i = 0; i < DBG_HEAP_HASHSIZE; i++ )
{
rootptr = hashTable[ i ];
for( ref = rootptr; ref != NULL; ref = next )
{
next = ref->next;
free( ref );
}
}
rootptr = NULL;
*/
}
refptr_t *DbgHeap::FindReference
(
void *ptr
)
{
refptr_t *ref;
refptr_t *rootptr;
rootptr = hashTable[ ( ( size_t )ptr / 8 ) % DBG_HEAP_HASHSIZE ];
for( ref = rootptr; ref != NULL; ref = ref->next )
{
if( ref->ptr == ptr )
return ref;
}
return NULL;
}
void DbgHeap::ReferencePointer
(
void *ptr
)
{
refptr_t *ref = FindReference( ptr );
refptr_t **rootptr;
if( !ref )
{
ref = ( refptr_t * )malloc( sizeof( refptr_t ) );
ref->ptr = ptr;
ref->refcount = 0;
ref->next = NULL;
#ifdef WIN32
RtlCaptureStackBackTrace( 1, DBG_HEAP_MAX_CALLSTACK, ref->callstack, NULL );
#endif
rootptr = &hashTable[ ( ( size_t )ptr / 8 ) % DBG_HEAP_HASHSIZE ];
if( !*rootptr )
{
*rootptr = ref;
}
else
{
ref->next = *rootptr;
*rootptr = ref;
}
}
// Increase the reference count
ref->refcount++;
}
void DbgHeap::DereferencePointer
(
void *ptr
)
{
refptr_t *ref = FindReference( ptr );
assert( ref );
if( !ref )
{
// Trying to dereference a non-existing pointer
exit( EXIT_FAILURE );
return;
}
assert( ref->refcount > 0 );
if( !ref->refcount )
{
// Trying to dereference an unreferenced pointer
exit( EXIT_FAILURE );
return;
}
ref->refcount--;
#ifdef WIN32
RtlCaptureStackBackTrace( 1, DBG_HEAP_MAX_CALLSTACK, ref->callstack, NULL );
#endif
}
void *operator new( size_t size )
{
void *ptr = malloc( size );
m_Heap.ReferencePointer( ptr );
return ptr;
}
void *operator new[]( size_t size )
{
void *ptr = malloc( size );
m_Heap.ReferencePointer( ptr );
return ptr;
}
void operator delete( void *ptr )
{
m_Heap.DereferencePointer( ptr );
free( ptr );
}
void operator delete[]( void *ptr )
{
m_Heap.DereferencePointer( ptr );
free( ptr );
}