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

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997.
  5. //
  6. // File: mydebug.hxx
  7. //
  8. // Contents: Functions to manage the debug heap
  9. //
  10. // Classes: ( none )
  11. //
  12. // Functions: void* operator new( size_t )
  13. // void* operator new( size_t, const char*, int )
  14. // void* my_new( size_t, const char*, int )
  15. // void operator delete( void* )
  16. //
  17. // Coupling:
  18. //
  19. // Notes: To enable the debug version, include this header file, use the
  20. // NEW macro instead of the new keyword, and include the following
  21. // line in your sources file:
  22. // DEBUG_CRTS=1
  23. //
  24. // History: 10-20-1996 ericne Created
  25. //
  26. //----------------------------------------------------------------------------
  27. #ifndef _MYDEBUG_
  28. #define _MYDEBUG_
  29. #ifdef NEW
  30. #undef NEW // Redefined later
  31. #endif
  32. #include <crtdbg.h>
  33. #ifdef _DEBUG_BLDCRT
  34. #include <malloc.h>
  35. #include <new.h>
  36. // If this is a multi-threaded application
  37. #ifdef _MT
  38. static class CDebugCriticalSection
  39. {
  40. CRITICAL_SECTION m_crit_sect;
  41. public:
  42. CDebugCriticalSection()
  43. {
  44. InitializeCriticalSection( &m_crit_sect );
  45. }
  46. ~CDebugCriticalSection()
  47. {
  48. DeleteCriticalSection( &m_crit_sect );
  49. }
  50. void Enter()
  51. {
  52. EnterCriticalSection( &m_crit_sect );
  53. }
  54. void Leave()
  55. {
  56. LeaveCriticalSection( &m_crit_sect );
  57. }
  58. } g_NewCriticalSection;
  59. #endif
  60. //+--------------------------------------------------------------------
  61. //
  62. // Function: my_new
  63. //
  64. // Synopsis: performs an allocation on the debug heap. Calls the
  65. // new handler if necessary.
  66. //
  67. // Arguments: [size] -- the number of bytes to allocate
  68. // [file] -- the name of the file which made the call
  69. // [line] -- the line number of the call
  70. //
  71. // Returns: NULL if it fails, a valid pointer otherwise
  72. //
  73. // History: 10-20-1996 ericne Created
  74. //
  75. // Notes:
  76. //
  77. //---------------------------------------------------------------------
  78. inline void * __cdecl my_new( size_t size, const char* file, int line )
  79. {
  80. void *pvoid = NULL;
  81. _PNH old_new_handler = NULL;
  82. #ifdef _MT
  83. __try
  84. {
  85. g_NewCriticalSection.Enter();
  86. #endif
  87. do
  88. {
  89. // Call _malloc_dbg to allocate space on the debug heap
  90. pvoid = _malloc_dbg( size, _NORMAL_BLOCK, file, line );
  91. // if the allocation succeeded, break
  92. if( NULL != pvoid )
  93. break;
  94. // if new_mode is 1, then malloc calls the new handler upon
  95. // failure -- it souldn't be called again.
  96. if( 1 == _query_new_mode( ) )
  97. break;
  98. // If there is no new handler, break
  99. if( NULL == ( old_new_handler = _query_new_handler( ) ) )
  100. break;
  101. #ifdef _MT
  102. // Getting ready to call the new handler
  103. // -- leave the critical section
  104. g_NewCriticalSection.Leave( );
  105. #endif
  106. // If the new handler returns 0, don't retry
  107. if( 0 == (*old_new_handler)( size ) )
  108. {
  109. #ifdef _MT
  110. g_NewCriticalSection.Enter( );
  111. #endif
  112. break;
  113. }
  114. #ifdef _MT
  115. // Re-enter the critical section
  116. g_NewCriticalSection.Enter( );
  117. #endif
  118. } while( 1 );
  119. #ifdef _MT
  120. }
  121. __finally
  122. {
  123. g_NewCriticalSection.Leave( );
  124. }
  125. #endif
  126. // Return the pointer
  127. return( pvoid );
  128. } // my_new
  129. //+--------------------------------------------------------------------
  130. //
  131. // Function: new
  132. //
  133. // Synopsis: Calls my_new. This function is needed to shadow the
  134. // default global new operator
  135. //
  136. // Arguments: [size] -- The size of the memory to be allocated
  137. //
  138. // Returns: void *
  139. //
  140. // History: 10-20-1996 ericne Created
  141. //
  142. // Notes:
  143. //
  144. //---------------------------------------------------------------------
  145. inline void * __cdecl operator new( size_t size )
  146. {
  147. return( my_new( size, NULL, 0 ) );
  148. } // new
  149. //+--------------------------------------------------------------------
  150. //
  151. // Function: new
  152. //
  153. // Synopsis: Calls my_new.
  154. //
  155. // Arguments: [size] -- Size of the user's memory block
  156. // [file] -- name of source file requesting the allocation
  157. // [line] -- line in source file of allocation request
  158. //
  159. // Returns:
  160. //
  161. // History: 10-20-1996 ericne Created
  162. //
  163. // Notes: If you use the NEW macro, this function will be called
  164. // with __FILE__ and __LINE__ as the 2nd and 3rd params
  165. //
  166. //---------------------------------------------------------------------
  167. inline void * __cdecl operator new( size_t size,
  168. const char* file,
  169. int line )
  170. {
  171. return( my_new( size, file, line ) );
  172. } // new
  173. //+--------------------------------------------------------------------
  174. //
  175. // Function: delete
  176. //
  177. // Synopsis: calls _free_dbg to clean up the debug heap
  178. //
  179. // Arguments: [pMemory] -- pointer to the users memory
  180. //
  181. // Returns: void
  182. //
  183. // History: 10-20-1996 ericne Created
  184. //
  185. // Notes:
  186. //
  187. //---------------------------------------------------------------------
  188. inline void __cdecl operator delete( void *pMemory )
  189. {
  190. // free the memory
  191. _free_dbg( pMemory, _NORMAL_BLOCK );
  192. } // delete
  193. #define NEW new( __FILE__, __LINE__ )
  194. #define DEBUG_INIT( ) \
  195. _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); \
  196. _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT ); \
  197. _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); \
  198. _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT )
  199. #define SET_CRT_DEBUG_FIELD( field ) \
  200. _CrtSetDbgFlag( (field) | _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) )
  201. #define CLEAR_CRT_DEBUG_FIELD( field ) \
  202. _CrtSetDbgFlag( ~(field) & _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) )
  203. // This object ensures that the debug settings are set even before
  204. // main begins
  205. static class DebugInit
  206. {
  207. public:
  208. DebugInit()
  209. {
  210. // Initialize the debug session
  211. DEBUG_INIT();
  212. // Memory check at termination
  213. SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF );
  214. }
  215. } g_Debug_Is_Initialized;
  216. #else
  217. #define NEW new
  218. #define DEBUG_INIT( ) ( (void) 0 )
  219. #define SET_CRT_DEBUG_FIELD( field ) ( (void) 0 )
  220. #define CLEAR_CRT_DEBUG_FIELD( field ) ( (void) 0 )
  221. #endif
  222. #endif