Source code of Windows XP (NT5)
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.

310 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1994-2000 Microsoft Corporation
  3. Module Name:
  4. heappagi.h
  5. Abstract:
  6. The following definitions are internal to the debug heap manager,
  7. but are placed in this include file so that debugger extensions
  8. can reference the same structure definitions. The following
  9. definitions are not intended to be referenced externally except
  10. by debugger extensions.
  11. Author:
  12. Tom McGuire (TomMcg) 06-Jan-1995
  13. Silviu Calinoiu (SilviuC) 22-Feb-2000
  14. Revision History:
  15. --*/
  16. #ifndef _HEAP_PAGE_I_
  17. #define _HEAP_PAGE_I_
  18. #ifdef DEBUG_PAGE_HEAP
  19. #include "heap.h"
  20. #define DPH_INTERNAL_DEBUG 0 // change to 0 or #undef for production code
  21. //
  22. // Stack trace size.
  23. //
  24. #define DPH_MAX_STACK_LENGTH 16
  25. //
  26. // Capture stacktraces in any context (x86/alpha, fre/chk). On alpha
  27. // the stack acquisition function will fail and no stack trace will be
  28. // acquired but in case we will find a better algorithm the page heap
  29. // code will automatically take advantage of that.
  30. //
  31. #define DPH_CAPTURE_STACK_TRACE 1
  32. //
  33. // DPH_HEAP_BLOCK
  34. //
  35. typedef struct _DPH_HEAP_BLOCK DPH_HEAP_BLOCK, *PDPH_HEAP_BLOCK;
  36. struct _DPH_HEAP_BLOCK {
  37. //
  38. // Singly linked list of allocations (pNextAlloc must be
  39. // first member in structure).
  40. //
  41. PDPH_HEAP_BLOCK pNextAlloc;
  42. //
  43. // | PAGE_READWRITE | PAGE_NOACCESS |
  44. // |____________________|___||_________________________|
  45. //
  46. // ^pVirtualBlock ^pUserAllocation
  47. //
  48. // |---------------- nVirtualBlockSize ----------------|
  49. //
  50. // |---nVirtualAccessSize----|
  51. //
  52. // |---| nUserRequestedSize
  53. //
  54. // |----| nUserActualSize
  55. //
  56. PUCHAR pVirtualBlock;
  57. SIZE_T nVirtualBlockSize;
  58. SIZE_T nVirtualAccessSize;
  59. PUCHAR pUserAllocation;
  60. SIZE_T nUserRequestedSize;
  61. SIZE_T nUserActualSize;
  62. PVOID UserValue;
  63. ULONG UserFlags;
  64. PRTL_TRACE_BLOCK StackTrace;
  65. };
  66. typedef struct _DPH_HEAP_ROOT DPH_HEAP_ROOT, *PDPH_HEAP_ROOT;
  67. struct _DPH_HEAP_ROOT {
  68. //
  69. // Maintain a signature (DPH_HEAP_SIGNATURE) as the
  70. // first value in the heap root structure.
  71. //
  72. ULONG Signature;
  73. ULONG HeapFlags;
  74. //
  75. // Access to this heap is synchronized with a critical section.
  76. //
  77. PRTL_CRITICAL_SECTION HeapCritSect;
  78. ULONG nRemoteLockAcquired;
  79. //
  80. // The "VirtualStorage" list only uses the pVirtualBlock,
  81. // nVirtualBlockSize, and nVirtualAccessSize fields of the
  82. // HEAP_ALLOCATION structure. This is the list of virtual
  83. // allocation entries that all the heap allocations are
  84. // taken from.
  85. //
  86. PDPH_HEAP_BLOCK pVirtualStorageListHead;
  87. PDPH_HEAP_BLOCK pVirtualStorageListTail;
  88. ULONG nVirtualStorageRanges;
  89. SIZE_T nVirtualStorageBytes;
  90. //
  91. // The "Busy" list is the list of active heap allocations.
  92. // It is stored in LIFO order to improve temporal locality
  93. // for linear searches since most initial heap allocations
  94. // tend to remain permanent throughout a process's lifetime.
  95. //
  96. PDPH_HEAP_BLOCK pBusyAllocationListHead;
  97. PDPH_HEAP_BLOCK pBusyAllocationListTail;
  98. ULONG nBusyAllocations;
  99. SIZE_T nBusyAllocationBytesCommitted;
  100. //
  101. // The "Free" list is the list of freed heap allocations, stored
  102. // in FIFO order to increase the length of time a freed block
  103. // remains on the freed list without being used to satisfy an
  104. // allocation request. This increases the odds of catching
  105. // a reference-after-freed bug in an app.
  106. //
  107. PDPH_HEAP_BLOCK pFreeAllocationListHead;
  108. PDPH_HEAP_BLOCK pFreeAllocationListTail;
  109. ULONG nFreeAllocations;
  110. SIZE_T nFreeAllocationBytesCommitted;
  111. //
  112. // The "Available" list is stored in address-sorted order to facilitate
  113. // coalescing. When an allocation request cannot be satisfied from the
  114. // "Available" list, it is attempted from the free list. If it cannot
  115. // be satisfied from the free list, the free list is coalesced into the
  116. // available list. If the request still cannot be satisfied from the
  117. // coalesced available list, new VM is added to the available list.
  118. //
  119. PDPH_HEAP_BLOCK pAvailableAllocationListHead;
  120. PDPH_HEAP_BLOCK pAvailableAllocationListTail;
  121. ULONG nAvailableAllocations;
  122. SIZE_T nAvailableAllocationBytesCommitted;
  123. //
  124. // The "UnusedNode" list is simply a list of available node
  125. // entries to place "Busy", "Free", or "Virtual" entries.
  126. // When freed nodes get coalesced into a single free node,
  127. // the other "unused" node goes on this list. When a new
  128. // node is needed (like an allocation not satisfied from the
  129. // free list), the node comes from this list if it's not empty.
  130. //
  131. PDPH_HEAP_BLOCK pUnusedNodeListHead;
  132. PDPH_HEAP_BLOCK pUnusedNodeListTail;
  133. ULONG nUnusedNodes;
  134. SIZE_T nBusyAllocationBytesAccessible;
  135. //
  136. // Node pools need to be tracked so they can be protected
  137. // from app scribbling on them.
  138. //
  139. PDPH_HEAP_BLOCK pNodePoolListHead;
  140. PDPH_HEAP_BLOCK pNodePoolListTail;
  141. ULONG nNodePools;
  142. SIZE_T nNodePoolBytes;
  143. //
  144. // Doubly linked list of DPH heaps in process is tracked through this.
  145. //
  146. PDPH_HEAP_ROOT pNextHeapRoot;
  147. PDPH_HEAP_ROOT pPrevHeapRoot;
  148. ULONG nUnProtectionReferenceCount;
  149. ULONG InsideAllocateNode; // only for debugging
  150. //
  151. // These are extra flags used to control page heap behavior.
  152. // During heap creation the current value of the global page heap
  153. // flags (process wise) is written into this field.
  154. //
  155. ULONG ExtraFlags;
  156. //
  157. // Seed for the random generator used to decide from where
  158. // should we make an allocation (normal or verified heap).
  159. // The field is protected by the critical section associated
  160. // with each page heap.
  161. //
  162. ULONG Seed;
  163. //
  164. // `NormalHeap' is used in case we want to combine verified allocations
  165. // with normal ones. This is useful to minimize memory impact. Without
  166. // this feature certain processes that are very heap intensive cannot
  167. // be verified at all.
  168. //
  169. PVOID NormalHeap;
  170. //
  171. // Heap creation stack trace.
  172. //
  173. PRTL_TRACE_BLOCK CreateStackTrace;
  174. //
  175. // Thread ID of the first thread inside the heap.
  176. //
  177. HANDLE FirstThread;
  178. };
  179. //
  180. // DPH_BLOCK_INFORMATION
  181. //
  182. // This structure is stored in every page heap allocated block.
  183. // This information is not saved if the catch backward overruns
  184. // flag is set.
  185. //
  186. #define DPH_NORMAL_BLOCK_START_STAMP_ALLOCATED 0xABCDAAAA
  187. #define DPH_NORMAL_BLOCK_END_STAMP_ALLOCATED 0xDCBAAAAA
  188. #define DPH_NORMAL_BLOCK_START_STAMP_FREE (0xABCDAAAA - 1)
  189. #define DPH_NORMAL_BLOCK_END_STAMP_FREE (0xDCBAAAAA - 1)
  190. #define DPH_PAGE_BLOCK_START_STAMP_ALLOCATED 0xABCDBBBB
  191. #define DPH_PAGE_BLOCK_END_STAMP_ALLOCATED 0xDCBABBBB
  192. #define DPH_PAGE_BLOCK_START_STAMP_FREE (0xABCDBBBB - 1)
  193. #define DPH_PAGE_BLOCK_END_STAMP_FREE (0xDCBABBBB - 1)
  194. #define DPH_NORMAL_BLOCK_SUFFIX 0xA0
  195. #define DPH_PAGE_BLOCK_PREFIX 0xB0
  196. #define DPH_PAGE_BLOCK_INFIX 0xC0
  197. #define DPH_PAGE_BLOCK_SUFFIX 0xD0
  198. #define DPH_NORMAL_BLOCK_INFIX 0xE0
  199. #define DPH_FREE_BLOCK_INFIX 0xF0
  200. typedef struct _DPH_BLOCK_INFORMATION {
  201. ULONG StartStamp;
  202. PVOID Heap;
  203. SIZE_T RequestedSize;
  204. SIZE_T ActualSize;
  205. union {
  206. LIST_ENTRY FreeQueue;
  207. USHORT TraceIndex;
  208. };
  209. PVOID StackTrace;
  210. ULONG EndStamp;
  211. //
  212. // (SilviuC): This structure needs to be 8-byte aligned.
  213. // If it is not, applications expecting aligned blocks will get
  214. // unaligned ones because this structure will prefix their
  215. // allocations. Internet Explorer is one such application
  216. // that stops working in these conditions.
  217. //
  218. } DPH_BLOCK_INFORMATION, * PDPH_BLOCK_INFORMATION;
  219. //
  220. // Error reasons used in debug messages
  221. //
  222. #define DPH_SUCCESS 0x0000
  223. #define DPH_ERROR_CORRUPTED_START_STAMP 0x0001
  224. #define DPH_ERROR_CORRUPTED_END_STAMP 0x0002
  225. #define DPH_ERROR_CORRUPTED_HEAP_POINTER 0x0004
  226. #define DPH_ERROR_CORRUPTED_PREFIX_PATTERN 0x0008
  227. #define DPH_ERROR_CORRUPTED_SUFFIX_PATTERN 0x0010
  228. #define DPH_ERROR_RAISED_EXCEPTION 0x0020
  229. #define DPH_ERROR_NO_NORMAL_HEAP 0x0040
  230. #define DPH_ERROR_CORRUPTED_INFIX_PATTERN 0x0080
  231. #define DPH_ERROR_DOUBLE_FREE 0x0100
  232. #endif // DEBUG_PAGE_HEAP
  233. #endif // _HEAP_PAGE_I_