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
7.1 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. replenish.c
  5. Abstract:
  6. Implements the replog command.
  7. Author:
  8. Michael Courage (mcourage) 3-Oct-2000
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. //
  15. // Private constants.
  16. //
  17. //
  18. // Private globals.
  19. //
  20. PSTR g_pReplenishActions[] =
  21. {
  22. "START REPLENISH",
  23. "END REPLENISH ",
  24. "QUEUE_REPLENISH",
  25. "INCREMENT ",
  26. "DECREMENT "
  27. };
  28. C_ASSERT( DIM(g_pReplenishActions) == REPLENISH_ACTION_COUNT );
  29. //
  30. // Public functions.
  31. //
  32. DECLARE_API( replog )
  33. /*++
  34. Routine Description:
  35. Dumps the replenish trace log.
  36. Arguments:
  37. None.
  38. Return Value:
  39. None.
  40. --*/
  41. {
  42. ULONG_PTR address = 0;
  43. ULONG_PTR context = 0;
  44. ULONG_PTR flags = 0;
  45. ULONG_PTR entryAddress;
  46. ULONG_PTR logPointer;
  47. ULONG result;
  48. TRACE_LOG logHeader;
  49. LONGLONG numEntries;
  50. REPLENISH_TRACE_LOG_ENTRY logEntry;
  51. PSTR pAction;
  52. LONGLONG index;
  53. ULONG offset1;
  54. ULONG offset2;
  55. CHAR invalidAction[sizeof("2047")];
  56. ULONG64 context64 = 0;
  57. ULONG64 flags64 = 0;
  58. SNAPSHOT_EXTENSION_DATA();
  59. //
  60. // Snag the optional context and flags from the command line.
  61. //
  62. if (GetExpressionEx(args, &context64, &args))
  63. GetExpressionEx(args, &flags64, &args);
  64. context = (ULONG_PTR) context64;
  65. flags = (ULONG_PTR) flags64;
  66. //
  67. // Find the log.
  68. //
  69. address = GetExpression( "&http!g_pReplenishTraceLog" );
  70. if (address == 0)
  71. {
  72. dprintf( "replog: cannot find http!g_pReplenishTraceLog\n" );
  73. return;
  74. }
  75. //
  76. // Read the pointer.
  77. //
  78. if (!ReadMemory(
  79. address,
  80. &logPointer,
  81. sizeof(logPointer),
  82. &result
  83. ))
  84. {
  85. dprintf(
  86. "replog: cannot read PTRACE_LOG @ %p\n",
  87. address
  88. );
  89. return;
  90. }
  91. //
  92. // Read the log header.
  93. //
  94. if (!ReadMemory(
  95. logPointer,
  96. &logHeader,
  97. sizeof(logHeader),
  98. &result
  99. ))
  100. {
  101. dprintf(
  102. "ref: cannot read TRACE_LOG @ %p\n",
  103. logPointer
  104. );
  105. return;
  106. }
  107. dprintf(
  108. "ref: log @ %p\n"
  109. " Signature = %08lx '%c%c%c%c' (%s)\n"
  110. " TypeSignature = %08lx '%c%c%c%c'\n"
  111. " LogSize = %lu\n"
  112. " NextEntry = %I64d\n"
  113. " EntrySize = %lu\n"
  114. " LogBuffer = %p\n",
  115. address,
  116. logHeader.Signature,
  117. DECODE_SIGNATURE(logHeader.Signature),
  118. logHeader.Signature == TRACE_LOG_SIGNATURE
  119. ? "OK"
  120. : logHeader.Signature == TRACE_LOG_SIGNATURE_X
  121. ? "FREED"
  122. : "INVALID",
  123. logHeader.TypeSignature,
  124. DECODE_SIGNATURE(logHeader.TypeSignature),
  125. logHeader.LogSize,
  126. logHeader.NextEntry,
  127. logHeader.EntrySize,
  128. logHeader.pLogBuffer
  129. );
  130. if (logHeader.pLogBuffer > ( (PUCHAR)address + sizeof(logHeader) ))
  131. {
  132. dprintf(
  133. " ExtraData @ %p\n",
  134. address + sizeof(logHeader)
  135. );
  136. }
  137. if (logHeader.Signature != TRACE_LOG_SIGNATURE &&
  138. logHeader.Signature != TRACE_LOG_SIGNATURE_X)
  139. {
  140. dprintf(
  141. "replog: log @ %p has invalid signature %08lx:\n",
  142. address,
  143. logHeader.Signature
  144. );
  145. return;
  146. }
  147. if (logHeader.EntrySize != sizeof(logEntry)
  148. || logHeader.TypeSignature != REPLENISH_TRACE_LOG_SIGNATURE)
  149. {
  150. dprintf(
  151. "replog: log @ %p is not a replenish trace log\n",
  152. address
  153. );
  154. return;
  155. }
  156. if (logHeader.NextEntry == -1)
  157. {
  158. dprintf(
  159. "replog: empty log @ %p\n",
  160. address
  161. );
  162. return;
  163. }
  164. //
  165. // Calculate the log size to dump.
  166. //
  167. if (logHeader.NextEntry < logHeader.LogSize)
  168. {
  169. numEntries = logHeader.NextEntry + 1;
  170. index = 0;
  171. }
  172. else
  173. {
  174. numEntries = logHeader.LogSize;
  175. index = (logHeader.NextEntry + 1) % logHeader.LogSize;
  176. }
  177. entryAddress = (ULONG_PTR)logHeader.pLogBuffer +
  178. (ULONG_PTR)( index * sizeof(logEntry) );
  179. if (entryAddress >=
  180. ( (ULONG_PTR)logHeader.pLogBuffer + (ULONG_PTR)( numEntries * sizeof(logEntry) ) ) )
  181. {
  182. dprintf(
  183. "replog: log @ %p has invalid data\n",
  184. address
  185. );
  186. return;
  187. }
  188. //
  189. // Dump the log.
  190. //
  191. for (;
  192. numEntries > 0 ;
  193. index++,
  194. numEntries--,
  195. entryAddress += sizeof(logEntry))
  196. {
  197. if (CheckControlC())
  198. {
  199. break;
  200. }
  201. if (index >= logHeader.LogSize)
  202. {
  203. index = 0;
  204. entryAddress = (ULONG_PTR)logHeader.pLogBuffer;
  205. }
  206. if (!ReadMemory(
  207. entryAddress,
  208. &logEntry,
  209. sizeof(logEntry),
  210. NULL
  211. ))
  212. {
  213. dprintf(
  214. "replog: cannot read memory @ %p\n",
  215. entryAddress
  216. );
  217. return;
  218. }
  219. if (context == 0 ||
  220. context == (ULONG_PTR)logEntry.pEndpoint)
  221. {
  222. if (logEntry.Action < REPLENISH_ACTION_COUNT)
  223. {
  224. pAction = g_pReplenishActions[logEntry.Action];
  225. }
  226. else
  227. {
  228. sprintf( invalidAction, "%lu", (ULONG)logEntry.Action );
  229. pAction = invalidAction;
  230. }
  231. dprintf(
  232. "CPU=%lu Endpoint=%p Act=%s"
  233. " oldCount=%3d %s newCount=%3d %s\n",
  234. logEntry.Processor,
  235. logEntry.pEndpoint,
  236. pAction,
  237. logEntry.Previous.IdleConnections,
  238. logEntry.Previous.ReplenishScheduled ? "S" : " ",
  239. logEntry.Current.IdleConnections,
  240. logEntry.Current.ReplenishScheduled ? "S" : " "
  241. );
  242. /*
  243. if (flags & 1)
  244. {
  245. dprintf(
  246. "\nCPU=%lu Conn=%I64x Req=%I64x Act=%s\n"
  247. " Time=%I64x ",
  248. (ULONG)logEntry.Processor,
  249. logEntry.ConnectionId,
  250. logEntry.RequestId,
  251. pAction,
  252. logEntry.TimeStamp,
  253. (logEntry.TimeStamp - PreviousTime),
  254. (logEntry.TimeStamp - PreviousTime) / 10
  255. );
  256. } else {
  257. dprintf(
  258. "C=%I64x R=%I64x A=%s ",
  259. logEntry.ConnectionId,
  260. logEntry.RequestId,
  261. pAction
  262. );
  263. }
  264. */
  265. }
  266. }
  267. } // replog