Leaked source code of windows server 2003
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

//+---------------------------------------------------------------------------
//
// 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