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.

329 lines
10 KiB

  1. #include "windows.h"
  2. #include "sxstypes.h"
  3. #define KDEXT_64BIT
  4. #include "wdbgexts.h"
  5. #include "fusiondbgext.h"
  6. #define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_RELEASE_ON_DEACTIVATION (0x00000001)
  7. #define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NO_DEACTIVATE (0x00000002)
  8. #define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_ON_FREE_LIST (0x00000004)
  9. #define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_HEAP_ALLOCATED (0x00000008)
  10. BOOL
  11. DumpActivationContextStackFrame(
  12. PCSTR pcsLineHeader,
  13. ULONG64 ulStackFrameAddress,
  14. ULONG ulDepth,
  15. DWORD dwFlags
  16. )
  17. {
  18. ULONG64 ulPreviousPtr = 0;
  19. ULONG64 ulActivationContextPointer = 0;
  20. ULONG ulFrameFlags = 0;
  21. if (!pcsLineHeader) pcsLineHeader = "";
  22. GetFieldValue(ulStackFrameAddress, "nt!_RTL_ACTIVATION_CONTEXT_STACK_FRAME", "Previous", ulPreviousPtr);
  23. GetFieldValue(ulStackFrameAddress, "nt!_RTL_ACTIVATION_CONTEXT_STACK_FRAME", "ActivationContext", ulActivationContextPointer);
  24. GetFieldValue(ulStackFrameAddress, "nt!_RTL_ACTIVATION_CONTEXT_STACK_FRAME", "Flags", ulFrameFlags);
  25. dprintf(
  26. "%sActivation stack frame @ 0x%p (depth %ld):\n"
  27. "%s Previous : 0x%p\n"
  28. "%s ActivationContext : 0x%p\n"
  29. "%s Flags : 0x%08lx ",
  30. pcsLineHeader, ulStackFrameAddress, ulDepth,
  31. pcsLineHeader, ulPreviousPtr,
  32. pcsLineHeader, ulActivationContextPointer,
  33. pcsLineHeader, ulFrameFlags);
  34. if (ulFrameFlags != 0)
  35. {
  36. dprintf("(");
  37. if (ulFrameFlags & RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_RELEASE_ON_DEACTIVATION)
  38. dprintf("ReleaseOnDeactivate ");
  39. if (ulFrameFlags & RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NO_DEACTIVATE)
  40. dprintf("NoDeactivate ");
  41. if (ulFrameFlags & RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_ON_FREE_LIST)
  42. dprintf("OnFreeList");
  43. if (ulFrameFlags & RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_HEAP_ALLOCATED)
  44. dprintf("HeapAllocated ");
  45. dprintf(")");
  46. }
  47. dprintf ("\n");
  48. return 0;
  49. }
  50. BOOL
  51. DumpActCtxStackFullStack(
  52. ULONG64 ulFirstStackFramePointer
  53. )
  54. {
  55. ULONG ulDepth = 0;
  56. ULONG64 ulStackFramePtr = ulFirstStackFramePointer;
  57. while (ulStackFramePtr)
  58. {
  59. DumpActivationContextStackFrame(" ", ulStackFramePtr, ulDepth++, 0xffff);
  60. GetFieldValue(ulStackFramePtr, "nt!_RTL_ACTIVATION_CONTEXT_STACK_FRAME", "Previous", ulStackFramePtr);
  61. if (CheckControlC() || (ulStackFramePtr == 0))
  62. break;
  63. }
  64. return TRUE;
  65. }
  66. BOOL
  67. DumpActCtxData(
  68. PCSTR LineHeader,
  69. const ULONG64 ActCtxDataAddressInDebugeeSpace,
  70. ULONG ulFlags
  71. )
  72. {
  73. //
  74. // ACTIVATION_CONTEXT_DATA is a self-referential type, so dumping it is
  75. // easy once it's all in memory.
  76. //
  77. ACTIVATION_CONTEXT_DATA ActData;
  78. BYTE *pbActualData = NULL;
  79. BOOL fOk = FALSE;
  80. ULONG cbRead = 0;
  81. if (!LineHeader) LineHeader = "";
  82. if (!ReadMemory(ActCtxDataAddressInDebugeeSpace, &ActData, sizeof(ActData), &cbRead) ||
  83. (cbRead != sizeof(ActData)))
  84. {
  85. dprintf(
  86. "%sFailed reading ACTIVATION_CONTEXT_DATA @ %p , or wrong kind of block is there.\n",
  87. LineHeader,
  88. ActCtxDataAddressInDebugeeSpace);
  89. goto Exit;
  90. }
  91. //
  92. // Let's create a blob of memory that can hold the whole thing, then
  93. //
  94. pbActualData = new BYTE[ActData.TotalSize];
  95. if (!pbActualData)
  96. {
  97. dprintf(
  98. "%sUnable to allocate %d bytes to store activation context data\n",
  99. LineHeader,
  100. ActData.TotalSize);
  101. goto Exit;
  102. }
  103. //
  104. // And re-read from the debugee
  105. //
  106. if (!ReadMemory(ActCtxDataAddressInDebugeeSpace, pbActualData, ActData.TotalSize, &cbRead) ||
  107. (cbRead != ActData.TotalSize))
  108. {
  109. dprintf(
  110. "%sUnable to read in %d bytes from %p as an activation context object?\n",
  111. LineHeader,
  112. ActData.TotalSize,
  113. ActCtxDataAddressInDebugeeSpace);
  114. goto Exit;
  115. }
  116. DbgExtPrintActivationContextData(
  117. (ulFlags & DUMPACTCTXDATA_FLAG_FULL) == DUMPACTCTXDATA_FLAG_FULL,
  118. (PCACTIVATION_CONTEXT_DATA)pbActualData,
  119. L" "
  120. );
  121. fOk = TRUE;
  122. Exit:
  123. if (pbActualData)
  124. delete[] pbActualData;
  125. return fOk;
  126. }
  127. BOOL
  128. DumpActCtx(
  129. const ULONG64 ActCtxAddressInDebugeeSpace,
  130. ULONG ulFlags
  131. )
  132. {
  133. ULONG64 ActCtxAddr = ActCtxAddressInDebugeeSpace;
  134. ULONG64 ulSymbolOffset = 0;
  135. PRIVATE_ACTIVATION_CONTEXT prvContextFilled = { 0 };
  136. CHAR NotificationSymbol[1024] = { 0 };
  137. BOOL fOk = FALSE;
  138. int i = 0;
  139. #define GET_FIELD(a, fn, dst) { GetFieldData((a), "nt!_ACTIVATION_CONTEXT", #fn, sizeof((dst).##fn), (PVOID)&((dst).##fn)); }
  140. GET_FIELD(ActCtxAddr, Flags, prvContextFilled);
  141. GET_FIELD(ActCtxAddr, RefCount, prvContextFilled);
  142. GET_FIELD(ActCtxAddr, ActivationContextData, prvContextFilled);
  143. GET_FIELD(ActCtxAddr, NotificationRoutine, prvContextFilled);
  144. GET_FIELD(ActCtxAddr, NotificationContext, prvContextFilled);
  145. // GET_FIELD(ActCtxAddr, SentNotifications, prvContextFilled);
  146. // GET_FIELD(ActCtxAddr, DisabledNotifications, prvContextFilled);
  147. // GET_FIELD(ActCtxAddr, StorageMap, prvContextFilled);
  148. // GET_FIELD(ActCtxAddr, InlineStorageMapEntries, prvContextFilled);
  149. #undef GET_FIELD
  150. dprintf(
  151. "Activation context structure @ 0x%p\n"
  152. " RefCount %d\n"
  153. " Flags 0x%08x\n"
  154. " ActivationContextData 0x%p\n",
  155. ActCtxAddressInDebugeeSpace,
  156. (LONG)prvContextFilled.RefCount,
  157. (ULONG)prvContextFilled.Flags,
  158. (PVOID)prvContextFilled.ActivationContextData);
  159. if (ulFlags & DUMPACTCTX_DATA)
  160. {
  161. // if (!DumpActCtxData(" ", (ULONG64)prvContextFilled.ActivationContextData, ulFlags))
  162. // goto Exit;
  163. DumpActCtxData(" ", (ULONG64)prvContextFilled.ActivationContextData, ulFlags);
  164. }
  165. //
  166. // This icky gunk is to print out a symbol name properly...
  167. //
  168. dprintf(" NotificationRoutine 0x%p ", prvContextFilled.NotificationRoutine);
  169. GetSymbol((ULONG64)prvContextFilled.NotificationRoutine, NotificationSymbol, &ulSymbolOffset);
  170. if (strlen(NotificationSymbol))
  171. {
  172. dprintf("(%s" , NotificationSymbol);
  173. if (ulSymbolOffset)
  174. dprintf("+0x%p", ulSymbolOffset);
  175. dprintf(")");
  176. }
  177. dprintf("\n");
  178. dprintf(" NotificationContext 0x%p\n", prvContextFilled.NotificationContext);
  179. dprintf(" SentNotifications [");
  180. for (i = 0; i < NUMBER_OF(prvContextFilled.SentNotifications); i++)
  181. {
  182. if (i) dprintf(" ");
  183. dprintf("%d", prvContextFilled.SentNotifications[i]);
  184. }
  185. dprintf("]\n");
  186. dprintf(" DisabledNotifications [");
  187. for (i = 0; i < NUMBER_OF(prvContextFilled.DisabledNotifications); i++)
  188. {
  189. if (i) dprintf(" ");
  190. dprintf("%d", prvContextFilled.DisabledNotifications[i]);
  191. }
  192. dprintf("]\n");
  193. {
  194. ULONG ulFlags, ulCount;
  195. ULONG64 ulMapAddress;
  196. GetFieldValue(ActCtxAddressInDebugeeSpace, "_ACTIVATION_CONTEXT", "StorageMap.Flags", ulFlags);
  197. GetFieldValue(ActCtxAddressInDebugeeSpace, "_ACTIVATION_CONTEXT", "StorageMap.AssemblyCount", ulCount);
  198. GetFieldValue(ActCtxAddressInDebugeeSpace, "_ACTIVATION_CONTEXT", "StorageMap.AssemblyArray", ulMapAddress);
  199. dprintf(
  200. " StorageMap (Flags = 0x%08lx Count = %d MapArray = %p)\n",
  201. ulFlags,
  202. ulCount,
  203. ulMapAddress);
  204. }
  205. fOk = TRUE;
  206. return fOk;
  207. }
  208. BOOL
  209. GetActiveActivationContextData(
  210. PULONG64 pulActiveActCtx
  211. )
  212. {
  213. ULONG64 ulTebAddress = 0, ulPebAddress = 0;
  214. ULONG64 ulTebActiveFrameAddress = 0;
  215. //
  216. // The algorithm is like this:
  217. // - Look at Teb.ActivationContextStack.ActiveFrame.ActivationContext. If this is
  218. // nonzero, stop looking.
  219. // - Now look at the process default activation context in Peb.ActivationContextData.
  220. // If this is nonzero, stop looking.
  221. // - Look at the system default act ctx data, in Peb.SystemDefaultActivationContextData
  222. // If this is nonzero, stop looking.
  223. // - Didn't find any active activation context data? Fooey.
  224. //
  225. *pulActiveActCtx = 0;
  226. GetTebAddress(&ulTebAddress);
  227. GetPebAddress(0, &ulPebAddress);
  228. if (ulTebAddress != NULL)
  229. {
  230. // Look at the active stack frame in the teb
  231. GetFieldValue(ulTebAddress, "nt!TEB", "ActivationContextStack.ActiveFrame", ulTebActiveFrameAddress);
  232. if (ulTebActiveFrameAddress)
  233. {
  234. ULONG64 ulActivationContextFrame;
  235. // Get the pointer to the active activation context itself
  236. GetFieldValue(
  237. ulTebActiveFrameAddress,
  238. "nt!_RTL_ACTIVATION_CONTEXT_STACK_FRAME",
  239. "ActivationContext",
  240. ulActivationContextFrame);
  241. // If that was valid, then ask for the pointer to the activation context data
  242. if (ulActivationContextFrame)
  243. {
  244. GetFieldValue(
  245. ulActivationContextFrame,
  246. "nt!ACTIVATION_CONTEXT",
  247. "ActivationContextData",
  248. *pulActiveActCtx);
  249. return TRUE;
  250. }
  251. // Is this really requesting the process default?
  252. else if (ulActivationContextFrame == NULL)
  253. {
  254. // Then get it and return
  255. GetFieldValue(ulPebAddress, "nt!PEB", "ActivationContextData", *pulActiveActCtx);
  256. return TRUE;
  257. }
  258. }
  259. }
  260. //
  261. // Still nothing, so go look at the process default directly
  262. //
  263. GetFieldValue(ulPebAddress, "nt!PEB", "ActivationContextData", *pulActiveActCtx);
  264. if (*pulActiveActCtx)
  265. {
  266. return TRUE;
  267. }
  268. //
  269. // Otherwise...
  270. //
  271. GetFieldValue(ulPebAddress, "nt!PEB", "SystemDefaultActivationContextData", *pulActiveActCtx);
  272. return (*pulActiveActCtx ? TRUE : FALSE);
  273. }