Team Fortress 2 Source Code as on 22/4/2020
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.

318 lines
7.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: This header, which must be the final include in a .cpp (or .h) file,
  4. // causes all crt methods to use debugging versions of the memory allocators.
  5. // NOTE: Use memdbgoff.h to disable memory debugging.
  6. //
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. // SPECIAL NOTE! This file must *not* use include guards; we need to be able
  10. // to include this potentially multiple times (since we can deactivate debugging
  11. // by including memdbgoff.h)
  12. #if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
  13. // SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!!
  14. #if defined(_DEBUG) && !defined(USE_MEM_DEBUG)
  15. #define USE_MEM_DEBUG 1
  16. #endif
  17. // If debug build or ndebug and not already included MS custom alloc files, or already included this file
  18. #if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H)
  19. #include "basetypes.h"
  20. #ifdef _WIN32
  21. #include <tchar.h>
  22. #else
  23. #include <wchar.h>
  24. #endif
  25. #include <string.h>
  26. #include <malloc.h>
  27. #include "commonmacros.h"
  28. #include "memalloc.h"
  29. #if defined(USE_MEM_DEBUG)
  30. #if defined( POSIX )
  31. #define _NORMAL_BLOCK 1
  32. #include <cstddef>
  33. #include <glob.h>
  34. #include <new>
  35. #include <sys/types.h>
  36. #if !defined( DID_THE_OPERATOR_NEW )
  37. #define DID_THE_OPERATOR_NEW
  38. // posix doesn't have a new of this form, so we impl our own
  39. #ifdef OSX
  40. void* operator new( size_t nSize, int blah, const char *pFileName, int nLine ) throw (std::bad_alloc);
  41. void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine ) throw (std::bad_alloc);
  42. #else
  43. void* operator new( size_t nSize, int blah, const char *pFileName, int nLine );
  44. void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine );
  45. #endif
  46. #endif
  47. #else // defined(POSIX)
  48. // Include crtdbg.h and make sure _DEBUG is set to 1.
  49. #if !defined(_DEBUG)
  50. #define _DEBUG 1
  51. #include <crtdbg.h>
  52. #undef _DEBUG
  53. #else
  54. #include <crtdbg.h>
  55. #endif // !defined(_DEBUG)
  56. #endif // defined(POSIX)
  57. #endif
  58. #include "tier0/memdbgoff.h"
  59. // --------------------------------------------------------
  60. // Debug/non-debug agnostic elements
  61. #define MEM_OVERRIDE_ON 1
  62. #undef malloc
  63. #undef realloc
  64. #undef calloc
  65. #undef _expand
  66. #undef free
  67. #undef _msize
  68. #undef _aligned_malloc
  69. #undef _aligned_free
  70. #ifndef MEMDBGON_H
  71. inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nElementSize)
  72. {
  73. memset(pMem, 0, nElementSize * nCount);
  74. return pMem;
  75. }
  76. #endif
  77. #define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s)
  78. #define free(p) g_pMemAlloc->Free( p )
  79. #define _msize(p) g_pMemAlloc->GetSize( p )
  80. #define _expand(p, s) _expand_NoLongerSupported(p, s)
  81. #define _aligned_free( p ) MemAlloc_FreeAligned( p )
  82. // --------------------------------------------------------
  83. // Debug path
  84. #if defined(USE_MEM_DEBUG)
  85. #define malloc(s) g_pMemAlloc->Alloc( s, __FILE__, __LINE__)
  86. #define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ )
  87. #define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a, __FILE__, __LINE__ )
  88. #ifdef _malloc_dbg
  89. #undef _malloc_dbg
  90. #endif
  91. #define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
  92. #if !defined( POSIX )
  93. #if defined(__AFX_H__) && defined(DEBUG_NEW)
  94. #define new DEBUG_NEW
  95. #else
  96. #undef new
  97. #define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
  98. #define new MEMALL_DEBUG_NEW
  99. #endif
  100. #endif
  101. #undef _strdup
  102. #undef strdup
  103. #undef _wcsdup
  104. #undef wcsdup
  105. #define _strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
  106. #define strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
  107. #define _wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
  108. #define wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
  109. // Make sure we don't define strdup twice
  110. #if !defined(MEMDBGON_H)
  111. inline char *MemAlloc_StrDup(const char *pString, const char *pFileName, unsigned nLine)
  112. {
  113. char *pMemory;
  114. if (!pString)
  115. return NULL;
  116. size_t len = strlen(pString) + 1;
  117. if ((pMemory = (char *)g_pMemAlloc->Alloc(len, pFileName, nLine)) != NULL)
  118. {
  119. return strcpy( pMemory, pString );
  120. }
  121. return NULL;
  122. }
  123. inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString, const char *pFileName, unsigned nLine)
  124. {
  125. wchar_t *pMemory;
  126. if (!pString)
  127. return NULL;
  128. size_t len = (wcslen(pString) + 1);
  129. if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL)
  130. {
  131. return wcscpy( pMemory, pString );
  132. }
  133. return NULL;
  134. }
  135. #endif // DBMEM_DEFINED_STRDUP
  136. #else
  137. // --------------------------------------------------------
  138. // Release path
  139. #define malloc(s) g_pMemAlloc->Alloc( s )
  140. #define realloc(p, s) g_pMemAlloc->Realloc( p, s )
  141. #define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a )
  142. #ifdef _malloc_dbg
  143. #undef _malloc_dbg
  144. #endif
  145. #define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
  146. #undef new
  147. #undef _strdup
  148. #undef strdup
  149. #undef _wcsdup
  150. #undef wcsdup
  151. #define _strdup(s) MemAlloc_StrDup(s)
  152. #define strdup(s) MemAlloc_StrDup(s)
  153. #define _wcsdup(s) MemAlloc_WcStrDup(s)
  154. #define wcsdup(s) MemAlloc_WcStrDup(s)
  155. // Make sure we don't define strdup twice
  156. #if !defined(MEMDBGON_H)
  157. inline char *MemAlloc_StrDup(const char *pString)
  158. {
  159. char *pMemory;
  160. if (!pString)
  161. return NULL;
  162. size_t len = strlen(pString) + 1;
  163. if ((pMemory = (char *)g_pMemAlloc->Alloc(len)) != NULL)
  164. {
  165. return strcpy( pMemory, pString );
  166. }
  167. return NULL;
  168. }
  169. inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString)
  170. {
  171. wchar_t *pMemory;
  172. if (!pString)
  173. return NULL;
  174. size_t len = (wcslen(pString) + 1);
  175. if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t))) != NULL)
  176. {
  177. return wcscpy( pMemory, pString );
  178. }
  179. return NULL;
  180. }
  181. #endif // DBMEM_DEFINED_STRDUP
  182. #endif // USE_MEM_DEBUG
  183. #define MEMDBGON_H // Defined here so can be used above
  184. #else
  185. #if defined(USE_MEM_DEBUG)
  186. #ifndef _STATIC_LINKED
  187. #pragma message ("Note: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build")
  188. #else
  189. #error "Error: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build. Not recoverable in static build"
  190. #endif
  191. #endif
  192. #endif // _INC_CRTDBG
  193. #else
  194. // Needed for MEM_ALLOC_CREDIT(), MemAlloc_Alloc(), etc.
  195. #include "memalloc.h"
  196. #if !defined( VALVE_ALLOCS_DEFINED )
  197. #define VALVE_ALLOCS_DEFINED
  198. #include "tier0/mem.h"
  199. inline void *valve_malloc_check_oom( size_t size )
  200. {
  201. void *ptr = malloc( size );
  202. if ( !ptr )
  203. MemAllocOOMError( size );
  204. return ptr;
  205. }
  206. inline void *valve_realloc_check_oom( void *ptr, size_t size )
  207. {
  208. void *ret = realloc( ptr, size );
  209. if ( !ret )
  210. MemAllocOOMError( size );
  211. return ret;
  212. }
  213. inline void *valve_calloc_check_oom( size_t num, size_t size )
  214. {
  215. void *ptr = calloc( num, size );
  216. if (!ptr)
  217. MemAllocOOMError( num * size );
  218. return ptr;
  219. }
  220. inline void *valve_memalign_check_oom( size_t alignment, size_t size )
  221. {
  222. void *ptr = memalign( alignment, size );
  223. if (!ptr)
  224. MemAllocOOMError(size);
  225. return ptr;
  226. }
  227. inline void *valve_aligned_malloc_check_oom( size_t size, size_t alignment )
  228. {
  229. void *ptr = _aligned_malloc( size, alignment );
  230. if (!ptr)
  231. MemAllocOOMError( size );
  232. return ptr;
  233. }
  234. #endif // VALVE_ALLOCS_DEFINED
  235. #define malloc valve_malloc_check_oom
  236. #define realloc valve_realloc_check_oom
  237. #define calloc valve_calloc_check_oom
  238. #define memalign valve_memalign_check_oom
  239. #define _aligned_malloc valve_aligned_malloc_check_oom
  240. #endif // !STEAM && !NO_MALLOC_OVERRIDE
  241. #if defined( NO_MALLOC_OVERRIDE )
  242. #undef malloc
  243. #undef realloc
  244. #undef calloc
  245. #undef memalign
  246. #undef _aligned_malloc
  247. #endif // NO_MALLOC_OVERRIDE