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.

256 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. thrdpool.c
  5. Abstract:
  6. Implements the thrdpool command.
  7. Author:
  8. Keith Moore (keithmo) 17-Jun-1998
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. //
  15. // Private constants.
  16. //
  17. //
  18. // Private types.
  19. //
  20. typedef struct _THREAD_ENUM_STATE
  21. {
  22. ULONG ThreadNumber;
  23. } THREAD_ENUM_STATE, *PTHREAD_ENUM_STATE;
  24. //
  25. // Private prototypes.
  26. //
  27. BOOLEAN
  28. DumpThreadPoolCallback(
  29. IN PLIST_ENTRY pRemoteListEntry,
  30. IN PVOID pContext
  31. );
  32. //
  33. // Public functions.
  34. //
  35. DECLARE_API( thrdpool )
  36. /*++
  37. Routine Description:
  38. Dumps the thread pool at the specified address.
  39. Arguments:
  40. None.
  41. Return Value:
  42. None.
  43. --*/
  44. {
  45. ULONG_PTR address = 0;
  46. CLONG count = 1;
  47. ULONG_PTR countAddress = 0;
  48. CLONG i;
  49. UL_THREAD_POOL threadPool;
  50. ULONG result;
  51. THREAD_ENUM_STATE state;
  52. SNAPSHOT_EXTENSION_DATA();
  53. state.ThreadNumber = 0;
  54. //
  55. // Snag the address from the command line.
  56. //
  57. address = GetExpression( args );
  58. if (address == 0)
  59. {
  60. address = GetExpression( "&http!g_UlThreadPool" );
  61. if (address == 0)
  62. {
  63. dprintf( "thrdpool: Cannot find http!g_UlThreadPool\n" );
  64. return;
  65. }
  66. countAddress = GetExpression( "&http!g_UlNumberOfProcessors" );
  67. if (countAddress == 0)
  68. {
  69. dprintf( "thrdpool: Cannot find http!g_UlNumberOfProcessors\n" );
  70. return;
  71. }
  72. if (!ReadMemory(
  73. countAddress,
  74. &count,
  75. sizeof(count),
  76. &result
  77. ))
  78. {
  79. dprintf(
  80. "thrdpool: Cannot read http!g_UlNumberOfProcessors at %p.\n",
  81. countAddress
  82. );
  83. return;
  84. }
  85. }
  86. if (address == 0)
  87. {
  88. PrintUsage( "thrdpool" );
  89. return;
  90. }
  91. // g_UlThreadPool[g_UlNumberOfProcessors] == WAIT_THREAD_POOL
  92. for (i = 0; i <= count; i++)
  93. {
  94. if (CheckControlC())
  95. {
  96. break;
  97. }
  98. //
  99. // Read the thread pool.
  100. //
  101. if (!ReadMemory(
  102. address,
  103. &threadPool,
  104. sizeof(threadPool),
  105. &result
  106. ))
  107. {
  108. dprintf(
  109. "thrdpool: cannot read UL_THREAD_POOL @ %p\n",
  110. address
  111. );
  112. return;
  113. }
  114. dprintf(
  115. "thrdpool: %sthread pool @ %p (%d)\n"
  116. " WorkQueueSList @ %p depth=%d\n"
  117. " WorkQueueEvent @ %p\n"
  118. " ThreadListHead @ %p%s\n"
  119. " pIrpThread = %p\n"
  120. " ThreadSpinLock @ %p\n"
  121. " Initialized = %s\n"
  122. " ThreadCount = %lu\n"
  123. " ThreadCpu = %lu\n",
  124. (i == count) ? "wait " : "",
  125. address,
  126. threadPool.ThreadCpu,
  127. REMOTE_OFFSET( address, UL_THREAD_POOL, WorkQueueSList ),
  128. SLIST_HEADER_DEPTH(&threadPool.WorkQueueSList),
  129. address + FIELD_OFFSET( UL_THREAD_POOL, WorkQueueEvent ),
  130. REMOTE_OFFSET( address, UL_THREAD_POOL, ThreadListHead ),
  131. IS_LIST_EMPTY(
  132. &threadPool,
  133. address,
  134. UL_THREAD_POOL,
  135. ThreadListHead
  136. ) ? " (EMPTY)" : "",
  137. threadPool.pIrpThread,
  138. address + FIELD_OFFSET( UL_THREAD_POOL, ThreadSpinLock ),
  139. threadPool.Initialized
  140. ? "TRUE"
  141. : "FALSE",
  142. (ULONG)threadPool.ThreadCount,
  143. (ULONG)threadPool.ThreadCpu
  144. );
  145. EnumLinkedList(
  146. (PLIST_ENTRY)REMOTE_OFFSET( address, UL_THREAD_POOL, ThreadListHead ),
  147. &DumpThreadPoolCallback,
  148. (PVOID)&state
  149. );
  150. address += sizeof(threadPool);
  151. }
  152. } // thrdpool
  153. BOOLEAN
  154. DumpThreadPoolCallback(
  155. IN PLIST_ENTRY pRemoteListEntry,
  156. IN PVOID pContext
  157. )
  158. {
  159. UL_THREAD_TRACKER localTracker;
  160. PUL_THREAD_TRACKER pRemoteTracker;
  161. PTHREAD_ENUM_STATE pState;
  162. ULONG result;
  163. CHAR temp[sizeof("1234567812345678 f")];
  164. pState = (PTHREAD_ENUM_STATE)pContext;
  165. pRemoteTracker = CONTAINING_RECORD(
  166. pRemoteListEntry,
  167. UL_THREAD_TRACKER,
  168. ThreadListEntry
  169. );
  170. if (!ReadMemory(
  171. (ULONG_PTR)pRemoteTracker,
  172. &localTracker,
  173. sizeof(localTracker),
  174. &result
  175. ))
  176. {
  177. dprintf( "thrdpool: cannot read UL_THREAD_TRACKER @ %p\n", pRemoteTracker );
  178. return FALSE;
  179. }
  180. sprintf( temp, "%p f", localTracker.pThread );
  181. #if 0
  182. dprintf( "About to `.thread %p f'\n", localTracker.pThread );
  183. // !kdexts.thread appears to be broken
  184. if (!CallExtensionRoutine( "thread", temp ))
  185. #endif // 0
  186. {
  187. dprintf(
  188. " %3lu : %p\n",
  189. pState->ThreadNumber,
  190. localTracker.pThread
  191. );
  192. pState->ThreadNumber++;
  193. }
  194. return TRUE;
  195. } // DumpThreadPoolCallback