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.

227 lines
4.4 KiB

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