You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
8.5 KiB
271 lines
8.5 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1997.
|
|
//
|
|
// File: mydebug.hxx
|
|
//
|
|
// Contents: Functions to manage the debug heap
|
|
//
|
|
// Classes: ( none )
|
|
//
|
|
// Functions: void* operator new( size_t )
|
|
// void* operator new( size_t, const char*, int )
|
|
// void* my_new( size_t, const char*, int )
|
|
// void operator delete( void* )
|
|
//
|
|
// Coupling:
|
|
//
|
|
// Notes: To enable the debug version, include this header file, use the
|
|
// NEW macro instead of the new keyword, and include the following
|
|
// line in your sources file:
|
|
// DEBUG_CRTS=1
|
|
//
|
|
// History: 10-20-1996 ericne Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#ifndef _MYDEBUG_
|
|
|
|
#define _MYDEBUG_
|
|
|
|
#ifdef NEW
|
|
#undef NEW // Redefined later
|
|
#endif
|
|
|
|
#include <crtdbg.h>
|
|
|
|
#ifdef _DEBUG_BLDCRT
|
|
|
|
#include <malloc.h>
|
|
#include <new.h>
|
|
|
|
// If this is a multi-threaded application
|
|
#ifdef _MT
|
|
static class CDebugCriticalSection
|
|
{
|
|
CRITICAL_SECTION m_crit_sect;
|
|
|
|
public:
|
|
CDebugCriticalSection()
|
|
{
|
|
InitializeCriticalSection( &m_crit_sect );
|
|
}
|
|
~CDebugCriticalSection()
|
|
{
|
|
DeleteCriticalSection( &m_crit_sect );
|
|
}
|
|
void Enter()
|
|
{
|
|
EnterCriticalSection( &m_crit_sect );
|
|
}
|
|
void Leave()
|
|
{
|
|
LeaveCriticalSection( &m_crit_sect );
|
|
}
|
|
|
|
} g_NewCriticalSection;
|
|
#endif
|
|
|
|
//+--------------------------------------------------------------------
|
|
//
|
|
// Function: my_new
|
|
//
|
|
// Synopsis: performs an allocation on the debug heap. Calls the
|
|
// new handler if necessary.
|
|
//
|
|
// Arguments: [size] -- the number of bytes to allocate
|
|
// [file] -- the name of the file which made the call
|
|
// [line] -- the line number of the call
|
|
//
|
|
// Returns: NULL if it fails, a valid pointer otherwise
|
|
//
|
|
// History: 10-20-1996 ericne Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
inline void * __cdecl my_new( size_t size, const char* file, int line )
|
|
{
|
|
|
|
void *pvoid = NULL;
|
|
_PNH old_new_handler = NULL;
|
|
|
|
#ifdef _MT
|
|
__try
|
|
{
|
|
g_NewCriticalSection.Enter();
|
|
#endif
|
|
do
|
|
{
|
|
// Call _malloc_dbg to allocate space on the debug heap
|
|
pvoid = _malloc_dbg( size, _NORMAL_BLOCK, file, line );
|
|
|
|
// if the allocation succeeded, break
|
|
if( NULL != pvoid )
|
|
break;
|
|
|
|
// if new_mode is 1, then malloc calls the new handler upon
|
|
// failure -- it souldn't be called again.
|
|
if( 1 == _query_new_mode( ) )
|
|
break;
|
|
|
|
// If there is no new handler, break
|
|
if( NULL == ( old_new_handler = _query_new_handler( ) ) )
|
|
break;
|
|
|
|
#ifdef _MT
|
|
// Getting ready to call the new handler
|
|
// -- leave the critical section
|
|
g_NewCriticalSection.Leave( );
|
|
#endif
|
|
|
|
// If the new handler returns 0, don't retry
|
|
if( 0 == (*old_new_handler)( size ) )
|
|
{
|
|
#ifdef _MT
|
|
g_NewCriticalSection.Enter( );
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
#ifdef _MT
|
|
// Re-enter the critical section
|
|
g_NewCriticalSection.Enter( );
|
|
#endif
|
|
|
|
} while( 1 );
|
|
|
|
#ifdef _MT
|
|
}
|
|
__finally
|
|
{
|
|
g_NewCriticalSection.Leave( );
|
|
}
|
|
#endif
|
|
|
|
// Return the pointer
|
|
return( pvoid );
|
|
|
|
} // my_new
|
|
|
|
//+--------------------------------------------------------------------
|
|
//
|
|
// Function: new
|
|
//
|
|
// Synopsis: Calls my_new. This function is needed to shadow the
|
|
// default global new operator
|
|
//
|
|
// Arguments: [size] -- The size of the memory to be allocated
|
|
//
|
|
// Returns: void *
|
|
//
|
|
// History: 10-20-1996 ericne Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
inline void * __cdecl operator new( size_t size )
|
|
{
|
|
|
|
return( my_new( size, NULL, 0 ) );
|
|
|
|
} // new
|
|
|
|
//+--------------------------------------------------------------------
|
|
//
|
|
// Function: new
|
|
//
|
|
// Synopsis: Calls my_new.
|
|
//
|
|
// Arguments: [size] -- Size of the user's memory block
|
|
// [file] -- name of source file requesting the allocation
|
|
// [line] -- line in source file of allocation request
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 10-20-1996 ericne Created
|
|
//
|
|
// Notes: If you use the NEW macro, this function will be called
|
|
// with __FILE__ and __LINE__ as the 2nd and 3rd params
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
inline void * __cdecl operator new( size_t size,
|
|
const char* file,
|
|
int line )
|
|
{
|
|
|
|
return( my_new( size, file, line ) );
|
|
|
|
} // new
|
|
|
|
//+--------------------------------------------------------------------
|
|
//
|
|
// Function: delete
|
|
//
|
|
// Synopsis: calls _free_dbg to clean up the debug heap
|
|
//
|
|
// Arguments: [pMemory] -- pointer to the users memory
|
|
//
|
|
// Returns: void
|
|
//
|
|
// History: 10-20-1996 ericne Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
inline void __cdecl operator delete( void *pMemory )
|
|
{
|
|
|
|
// free the memory
|
|
_free_dbg( pMemory, _NORMAL_BLOCK );
|
|
|
|
} // delete
|
|
|
|
#define NEW new( __FILE__, __LINE__ )
|
|
|
|
#define DEBUG_INIT( ) \
|
|
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); \
|
|
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT ); \
|
|
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); \
|
|
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT )
|
|
|
|
#define SET_CRT_DEBUG_FIELD( field ) \
|
|
_CrtSetDbgFlag( (field) | _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) )
|
|
|
|
#define CLEAR_CRT_DEBUG_FIELD( field ) \
|
|
_CrtSetDbgFlag( ~(field) & _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) )
|
|
|
|
// This object ensures that the debug settings are set even before
|
|
// main begins
|
|
static class DebugInit
|
|
{
|
|
public:
|
|
DebugInit()
|
|
{
|
|
// Initialize the debug session
|
|
DEBUG_INIT();
|
|
|
|
// Memory check at termination
|
|
SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF );
|
|
}
|
|
} g_Debug_Is_Initialized;
|
|
|
|
#else
|
|
|
|
#define NEW new
|
|
|
|
#define DEBUG_INIT( ) ( (void) 0 )
|
|
|
|
#define SET_CRT_DEBUG_FIELD( field ) ( (void) 0 )
|
|
|
|
#define CLEAR_CRT_DEBUG_FIELD( field ) ( (void) 0 )
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|