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.

324 lines
7.6 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Debuggee state buffers.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2000.
  6. //
  7. //----------------------------------------------------------------------------
  8. #ifndef __STATEBUF_H__
  9. #define __STATEBUF_H__
  10. // Different WU_UPDATE qualifiers, sent in WPARAM.
  11. enum UpdateType
  12. {
  13. UPDATE_BUFFER,
  14. UPDATE_BP,
  15. UPDATE_EXEC,
  16. UPDATE_INPUT_REQUIRED,
  17. UPDATE_START_SESSION,
  18. UPDATE_END_SESSION,
  19. UPDATE_PROMPT_TEXT,
  20. UPDATE_EXIT
  21. };
  22. typedef enum
  23. {
  24. MINVAL_WINDOW = 0,
  25. DOC_WINDOW,
  26. WATCH_WINDOW,
  27. LOCALS_WINDOW,
  28. CPU_WINDOW,
  29. DISASM_WINDOW,
  30. CMD_WINDOW,
  31. SCRATCH_PAD_WINDOW,
  32. MEM_WINDOW,
  33. QUICKW_WINDOW,
  34. CALLS_WINDOW,
  35. PROCESS_THREAD_WINDOW,
  36. MAXVAL_WINDOW,
  37. // Artificial values so there are well-defined bit
  38. // positions for state which is not tied to a specific window.
  39. EVENT_BIT,
  40. BP_BIT,
  41. BP_CMDS_BIT,
  42. FILTER_BIT,
  43. MODULE_BIT
  44. } WIN_TYPES, * PWIN_TYPES;
  45. #define FIRST_WINDOW ((WIN_TYPES)(MINVAL_WINDOW + 1))
  46. #define LAST_WINDOW ((WIN_TYPES)(MAXVAL_WINDOW - 1))
  47. //----------------------------------------------------------------------------
  48. //
  49. // StateBuffer.
  50. //
  51. // A state buffer is a dynamic container for data passed from
  52. // the engine thread to the UI thread. It may be used for
  53. // holding window content, in which case it will have an HWND
  54. // associated with it, or it can be an internal buffer for non-UI
  55. // purposes.
  56. //
  57. // A list of current window-associated state buffers is kept for
  58. // the engine to traverse when it is updating state for the UI.
  59. // The UI thread is the only thread that can add to this list.
  60. // The engine thread is the only thread that can remove a buffer
  61. // from the list. This is necessary for proper lifetime management
  62. // of dynamically-created buffers.
  63. //
  64. //----------------------------------------------------------------------------
  65. class StateBuffer : public LIST_ENTRY
  66. {
  67. public:
  68. DBG_CRITICAL_SECTION m_Lock;
  69. WIN_TYPES m_enumType;
  70. HWND m_Win;
  71. ULONG m_UpdateTypes;
  72. UpdateType m_UpdateType;
  73. StateBuffer(ULONG ChangeBy);
  74. virtual ~StateBuffer(void);
  75. PVOID AddData(ULONG Len);
  76. BOOL AddString(PCSTR Str, BOOL SoftTerminate);
  77. void RemoveHead(ULONG Len);
  78. void RemoveMiddle(ULONG Start, ULONG Len);
  79. void RemoveTail(ULONG Len);
  80. HRESULT Resize(ULONG Len);
  81. void Free(void);
  82. void Empty(void)
  83. {
  84. m_DataUsed = 0;
  85. }
  86. HRESULT GetStatus(void)
  87. {
  88. return m_Status;
  89. }
  90. void SetStatus(HRESULT Status)
  91. {
  92. m_Status = Status;
  93. }
  94. ULONG GetReadRequest(void)
  95. {
  96. return m_ReadRequest;
  97. }
  98. ULONG GetReadDone(void)
  99. {
  100. return m_ReadDone;
  101. }
  102. void RequestRead(void)
  103. {
  104. InterlockedIncrement((LONG *)&m_ReadRequest);
  105. }
  106. void SetReadDone(ULONG Done)
  107. {
  108. m_ReadDone = Done;
  109. }
  110. PVOID GetDataBuffer(void)
  111. {
  112. return m_Data;
  113. }
  114. ULONG GetDataLen(void)
  115. {
  116. return m_DataUsed;
  117. }
  118. HRESULT Update(void);
  119. void UiRequestRead(void);
  120. HRESULT UiLockForRead(void);
  121. // Base implementation just returns S_OK for
  122. // buffers maintained in other ways.
  123. // ReadState should only be called in the engine thread.
  124. virtual HRESULT ReadState(void);
  125. protected:
  126. void SetNoData(void)
  127. {
  128. m_Data = NULL;
  129. m_DataLen = 0;
  130. Empty();
  131. }
  132. ULONG m_ChangeBy;
  133. UINT m_UpdateMessage;
  134. HRESULT m_Status;
  135. ULONG m_ReadRequest;
  136. ULONG m_ReadDone;
  137. PBYTE m_Data;
  138. ULONG m_DataLen;
  139. ULONG m_DataUsed;
  140. };
  141. //----------------------------------------------------------------------------
  142. //
  143. // OutputToStateBuffer.
  144. //
  145. //----------------------------------------------------------------------------
  146. class OutputToStateBuffer : public DefOutputCallbacks
  147. {
  148. public:
  149. OutputToStateBuffer(void)
  150. {
  151. m_Buffer = NULL;
  152. }
  153. void SetBuffer(StateBuffer* Buffer)
  154. {
  155. m_Buffer = Buffer;
  156. }
  157. HRESULT Start(BOOL Empty);
  158. HRESULT End(BOOL RemoveLastNewLine);
  159. ULONG GetLineCount(void)
  160. {
  161. return m_NewLineCount + m_PartialLine;
  162. }
  163. ULONG RecountLines(void)
  164. {
  165. m_NewLineCount = 0;
  166. AddLines((PSTR)m_Buffer->GetDataBuffer() + m_DataStart);
  167. return GetLineCount();
  168. }
  169. void ReplaceChar(char From, char To);
  170. // IDebugOutputCallbacks.
  171. STDMETHOD(Output)(
  172. THIS_
  173. IN ULONG Mask,
  174. IN PCSTR Text
  175. );
  176. private:
  177. void AddLines(PCSTR Start);
  178. StateBuffer* m_Buffer;
  179. ULONG m_DataStart;
  180. HRESULT m_Status;
  181. ULONG m_NewLineCount;
  182. ULONG m_PartialLine;
  183. };
  184. extern OutputToStateBuffer g_OutStateBuf;
  185. extern OutputToStateBuffer g_UiOutStateBuf;
  186. //----------------------------------------------------------------------------
  187. //
  188. // Dynamic state buffers.
  189. //
  190. //----------------------------------------------------------------------------
  191. extern LIST_ENTRY g_StateList;
  192. // Global lock for short operations where it doesn't matter
  193. // if the threads block on each other briefly. This lock should
  194. // not be held longer than a fraction of a second.
  195. // Used for protecting:
  196. // State buffer list.
  197. // g_Event values.
  198. extern DBG_CRITICAL_SECTION g_QuickLock;
  199. #define LockStateBuffer(Buffer) Dbg_EnterCriticalSection(&(Buffer)->m_Lock)
  200. #define UnlockStateBuffer(Buffer) Dbg_LeaveCriticalSection(&(Buffer)->m_Lock)
  201. #define AssertStateBufferLocked(Buffer) \
  202. Assert(Dbg_CriticalSectionOwned(&(Buffer)->m_Lock))
  203. extern ULONG64 g_CodeIp;
  204. // If g_CodeFileFound[0] == 0 no source file was found.
  205. extern char g_CodeFileFound[];
  206. // If g_CodeSymFile[0] == 0 no source symbol information was found.
  207. extern char g_CodeSymFile[];
  208. extern ULONG g_CodeLine;
  209. extern BOOL g_CodeUserActivated;
  210. extern ULONG g_CodeBufferSequence;
  211. extern ULONG64 g_EventIp;
  212. extern ULONG64 g_EventReturnAddr;
  213. extern ULONG g_CurProcessId, g_CurProcessSysId;
  214. extern ULONG g_CurThreadId, g_CurThreadSysId;
  215. enum BpStateType
  216. {
  217. BP_ENABLED,
  218. BP_DISABLED,
  219. BP_NONE,
  220. BP_UNKNOWN
  221. };
  222. struct BpBufferData
  223. {
  224. ULONG64 Offset;
  225. ULONG Id;
  226. ULONG Flags;
  227. ULONG Thread;
  228. ULONG Sequence;
  229. ULONG FileOffset;
  230. };
  231. extern ULONG g_BpCount;
  232. extern StateBuffer* g_BpBuffer;
  233. extern ULONG g_BpTextOffset;
  234. extern StateBuffer* g_BpCmdsBuffer;
  235. extern StateBuffer* g_FilterTextBuffer;
  236. extern StateBuffer* g_FilterBuffer;
  237. extern ULONG g_FilterArgsOffset;
  238. extern ULONG g_FilterCmdsOffset;
  239. extern ULONG g_FilterWspCmdsOffset;
  240. extern ULONG g_NumSpecEvents, g_NumSpecEx, g_NumArbEx;
  241. extern StateBuffer* g_ModuleBuffer;
  242. extern ULONG g_NumModules;
  243. void FillCodeBuffer(ULONG64 Ip, BOOL UserActivated);
  244. void FillEventBuffer(void);
  245. void ReadStateBuffers(void);
  246. #define BUFFERS_ALL 0xffffffff
  247. void InvalidateStateBuffers(ULONG Types);
  248. void UpdateBufferWindows(ULONG Types, UpdateType Type);
  249. //----------------------------------------------------------------------------
  250. //
  251. // Static state buffers.
  252. //
  253. //----------------------------------------------------------------------------
  254. extern StateBuffer* g_RegisterNamesBuffer;
  255. extern StateBuffer* g_WatchWinBuffer;
  256. extern PUSHORT g_RegisterMap;
  257. extern ULONG g_RegisterMapEntries;
  258. #define MAP_REGISTER(i) \
  259. (g_RegisterMap != NULL && (i) < g_RegisterMapEntries ? \
  260. g_RegisterMap[(i)] : (i))
  261. void GetRegisterMapText(HWND Edit);
  262. void ScanRegisterMapText(HWND Edit);
  263. //----------------------------------------------------------------------------
  264. //
  265. // UI thread state buffer.
  266. //
  267. // The UI thread has simple needs and so one state buffer for
  268. // output capture is sufficient.
  269. //
  270. //----------------------------------------------------------------------------
  271. extern StateBuffer g_UiOutputCapture;
  272. #endif // #ifndef __STATEBUF_H__