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.

232 lines
4.8 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. STACKCOM.CPP
  5. Abstract:
  6. stack implementation.
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include <stdio.h>
  11. #ifdef _MT
  12. #undef _MT
  13. #include <yvals.h>
  14. #define _MT
  15. #endif
  16. #include "arena.h"
  17. #include "sync.h"
  18. #include "flexarry.h"
  19. #include <time.h>
  20. #include <stdio.h>
  21. #include <arrtempl.h>
  22. #include <sync.h>
  23. #include <malloc.h>
  24. #include <imagehlp.h>
  25. #include <execq.h>
  26. #include "stackcom.h"
  27. void* CStackRecord::mstatic_apReturns[1000];
  28. void CStackRecord::Create(int nIgnore, BOOL bStatic)
  29. {
  30. m_dwNumItems = GetStackLen() - nIgnore;
  31. if(bStatic)
  32. {
  33. m_apReturns = (void**)mstatic_apReturns;
  34. m_bDelete = FALSE;
  35. }
  36. else
  37. {
  38. m_apReturns = new void*[m_dwNumItems];
  39. m_bDelete = TRUE;
  40. }
  41. ReadStack(nIgnore, m_apReturns);
  42. }
  43. CStackRecord::~CStackRecord()
  44. {
  45. if(m_bDelete)
  46. delete m_apReturns;
  47. }
  48. void CStackRecord::MakeCopy(CStackRecord& Other)
  49. {
  50. m_dwNumItems = Other.GetNumItems();
  51. DWORD dwLen = Other.GetNumItems() * sizeof(void*);
  52. m_apReturns = new void*[Other.GetNumItems()];
  53. memcpy(m_apReturns, Other.GetItems(), dwLen);
  54. m_bDelete = TRUE;
  55. }
  56. int CStackRecord::Compare(const CStackRecord& Other) const
  57. {
  58. int nDiff = GetNumItems()- Other.GetNumItems();
  59. if(nDiff)
  60. return nDiff;
  61. return memcmp(GetItems(), Other.GetItems(), sizeof(void*) * GetNumItems());
  62. }
  63. DWORD CStackRecord::GetStackLen()
  64. {
  65. void* pFrame;
  66. __asm
  67. {
  68. mov pFrame, ebp
  69. }
  70. CStackContinuation* pPrev = CStackContinuation::Get();
  71. void* pEnd = NULL;
  72. if(pPrev)
  73. pEnd = pPrev->m_pThisStackEnd;
  74. DWORD dwLen = 0;
  75. while(!IsBadReadPtr(pFrame, sizeof(DWORD)))
  76. {
  77. dwLen++;
  78. void** ppReturn = (void**)pFrame + 1;
  79. void* pReturn = *ppReturn;
  80. if(pReturn == pEnd)
  81. break;
  82. void* pNewFrame = *(void**)pFrame;
  83. if(pNewFrame <= pFrame)
  84. break;
  85. pFrame = pNewFrame;
  86. }
  87. if(pPrev != NULL)
  88. dwLen += pPrev->m_pPrevStack->GetNumItems();
  89. return dwLen;
  90. }
  91. void CStackRecord::ReadStack(int nIgnore, void** apReturns)
  92. {
  93. void* pFrame;
  94. __asm
  95. {
  96. mov pFrame, ebp
  97. }
  98. CStackContinuation* pPrev = CStackContinuation::Get();
  99. void* pEnd = NULL;
  100. if(pPrev)
  101. pEnd = pPrev->m_pThisStackEnd;
  102. while(!IsBadReadPtr(pFrame, sizeof(DWORD)))
  103. {
  104. void** ppReturn = (void**)pFrame + 1;
  105. void* pReturn = *ppReturn;
  106. if(pReturn == pEnd)
  107. break;
  108. if(nIgnore == 0)
  109. *(apReturns++) = pReturn;
  110. else
  111. nIgnore--;
  112. void* pNewFrame = *(void**)pFrame;
  113. if(pNewFrame <= pFrame)
  114. break;
  115. pFrame = pNewFrame;
  116. }
  117. if(pPrev != NULL)
  118. {
  119. memcpy(apReturns, pPrev->m_pPrevStack->m_apReturns,
  120. sizeof(void*) * pPrev->m_pPrevStack->GetNumItems());
  121. }
  122. }
  123. void CStackRecord::Dump(FILE* f) const
  124. {
  125. fwrite(&m_dwNumItems, sizeof(DWORD), 1, f);
  126. fwrite(m_apReturns, sizeof(void*), m_dwNumItems, f);
  127. }
  128. BOOL CStackRecord::Read(FILE* f, BOOL bStatic)
  129. {
  130. if(fread(&m_dwNumItems, sizeof(DWORD), 1, f) == 0)
  131. return FALSE;
  132. if(bStatic)
  133. {
  134. m_apReturns = (void**)mstatic_apReturns;
  135. m_bDelete = FALSE;
  136. }
  137. else
  138. {
  139. m_apReturns = new void*[m_dwNumItems];
  140. m_bDelete = TRUE;
  141. }
  142. return (fread(m_apReturns, sizeof(void*), m_dwNumItems, f) != 0);
  143. }
  144. void CAllocRecord::Dump(FILE* f) const
  145. {
  146. fwrite(&m_dwTotalAlloc, sizeof(DWORD), 1, f);
  147. fwrite(&m_dwNumTimes, sizeof(DWORD), 1, f);
  148. m_Stack.Dump(f);
  149. DWORD dwNumBuffers = m_apBuffers.Size();
  150. fwrite(&dwNumBuffers, sizeof(DWORD), 1, f);
  151. fwrite(m_apBuffers.GetArrayPtr(), sizeof(void*), dwNumBuffers, f);
  152. }
  153. void CAllocRecord::Subtract(CAllocRecord& Other)
  154. {
  155. m_dwTotalAlloc -= Other.m_dwTotalAlloc;
  156. m_dwNumTimes -= Other.m_dwNumTimes;
  157. for(int i = 0; i < m_apBuffers.Size(); i++)
  158. {
  159. for(int j = 0; j < Other.m_apBuffers.Size(); j++)
  160. if(Other.m_apBuffers[j] == m_apBuffers[i])
  161. break;
  162. if(j < Other.m_apBuffers.Size())
  163. {
  164. m_apBuffers.RemoveAt(i);
  165. i--;
  166. }
  167. }
  168. }
  169. CTls CStackContinuation::mtls_CurrentCont;
  170. CStackContinuation* CStackContinuation::Set(CStackContinuation* pNew)
  171. {
  172. CStackContinuation* pPrev = (CStackContinuation*)(void*)mtls_CurrentCont;
  173. mtls_CurrentCont = pNew;
  174. if(pNew)
  175. {
  176. void* p;
  177. __asm
  178. {
  179. mov eax, [ebp]
  180. mov eax, [eax+4]
  181. mov p, eax
  182. }
  183. pNew->m_pThisStackEnd = p;
  184. }
  185. return pPrev;
  186. }
  187. CStackContinuation* CStackContinuation::Get()
  188. {
  189. CStackContinuation* pPrev = (CStackContinuation*)(void*)mtls_CurrentCont;
  190. return pPrev;
  191. }