Leaked source code of windows server 2003
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.

323 lines
8.3 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ready.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Ramon J San Andres (ramonsa) 8-Nov-1993
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. Jamie Hankins (a-jamhan) 20-Oct-1997 Added CheckControlC to loop.
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. HRESULT
  17. DumpReadyList(
  18. ULONG dwProcessor,
  19. ULONG Flags
  20. )
  21. /*++
  22. Routine Description:
  23. Arguments:
  24. args -
  25. Return Value:
  26. None
  27. --*/
  28. {
  29. ULONG64 DispatcherReadyListHead;
  30. ULONG HighestProcessor;
  31. LONG i;
  32. ULONG Index;
  33. ULONG ListEntrySize;
  34. ULONG MaximumProcessors;
  35. ULONG64 MemoryAddress;
  36. ULONG64 ProcessorBlock[64];
  37. ULONG PtrSize = DBG_PTR_SIZE;
  38. ULONG ReadyListHeadOffset;
  39. ULONG result;
  40. BOOLEAN ThreadDumped = FALSE;
  41. ULONG WaitListOpffset;
  42. //
  43. // Get number of processors.
  44. //
  45. MaximumProcessors = GetByteValue("nt!KeNumberProcessors");
  46. //
  47. // Get address of processor block array and read entire array.
  48. //
  49. MemoryAddress = GetExpression("nt!KiProcessorBlock");
  50. if (MemoryAddress == 0) {
  51. dprintf("Unable to read processor block array\n");
  52. return E_INVALIDARG;
  53. }
  54. HighestProcessor = 0;
  55. for (Index = 0; Index < MaximumProcessors; Index += 1) {
  56. if (!ReadPointer(MemoryAddress + Index * PtrSize, &ProcessorBlock[Index])) {
  57. dprintf("Unable to read processor block array\n");
  58. return E_INVALIDARG;
  59. }
  60. if (ProcessorBlock[Index] != 0) {
  61. HighestProcessor = Index;
  62. }
  63. }
  64. //
  65. // Get ready list head offset.
  66. //
  67. if (GetFieldOffset("nt!_KPRCB", "DispatcherReadyListHead", &ReadyListHeadOffset)) {
  68. dprintf("Unable to read KPRCB.DispatcherReadyListHead offset.\n");
  69. return E_INVALIDARG;
  70. }
  71. //
  72. // Scan the ready list for each processor.
  73. //
  74. for (Index = 0; Index <= HighestProcessor; Index += 1)
  75. {
  76. DispatcherReadyListHead = ProcessorBlock[Index];
  77. if ( DispatcherReadyListHead )
  78. {
  79. DispatcherReadyListHead += ReadyListHeadOffset;
  80. ListEntrySize = GetTypeSize("nt!_LIST_ENTRY");
  81. if (ListEntrySize == 0) {
  82. ListEntrySize = DBG_PTR_SIZE * 2;
  83. }
  84. GetFieldOffset("nt!_ETHREAD", "Tcb.WaitListEntry", &WaitListOpffset);
  85. for (i = MAXIMUM_PRIORITY-1; i >= 0 ; i -= 1 ) {
  86. ULONG64 Flink, Blink;
  87. if ( GetFieldValue( DispatcherReadyListHead + i*ListEntrySize,
  88. "nt!_LIST_ENTRY",
  89. "Flink",
  90. Flink) ) {
  91. dprintf(
  92. "Could not read contents of DispatcherReadyListHead at %08p [%ld]\n",
  93. (DispatcherReadyListHead + i * ListEntrySize), i);
  94. return E_INVALIDARG;
  95. }
  96. if (Flink != DispatcherReadyListHead+i*ListEntrySize) {
  97. ULONG64 ThreadEntry, ThreadFlink;
  98. dprintf("Ready Threads at priority %ld on processor %d\n", i, Index);
  99. for (ThreadEntry = Flink ;
  100. ThreadEntry != DispatcherReadyListHead+i*ListEntrySize ;
  101. ThreadEntry = ThreadFlink ) {
  102. ULONG64 ThreadBaseAddress = (ThreadEntry - WaitListOpffset);
  103. if ( GetFieldValue( ThreadBaseAddress,
  104. "nt!_ETHREAD",
  105. "Tcb.WaitListEntry.Flink",
  106. ThreadFlink) ) {
  107. dprintf("Could not read contents of thread %p\n", ThreadBaseAddress);
  108. }
  109. if(CheckControlC()) {
  110. return E_INVALIDARG;
  111. }
  112. DumpThread(dwProcessor," ", ThreadBaseAddress, Flags);
  113. ThreadDumped = TRUE;
  114. }
  115. } else {
  116. GetFieldValue( DispatcherReadyListHead + i*ListEntrySize,
  117. "nt!_LIST_ENTRY",
  118. "Blink",
  119. Blink);
  120. if (Flink != Blink) {
  121. dprintf("Ready linked list may to be corrupt...\n");
  122. }
  123. }
  124. }
  125. if (!ThreadDumped) {
  126. dprintf("No threads in READY state\n");
  127. }
  128. } else {
  129. dprintf("Could not determine address of DispatcherReadyListHead\n");
  130. return E_INVALIDARG;
  131. }
  132. }
  133. return S_OK;
  134. }
  135. HRESULT
  136. DumpReadyList_3598(
  137. ULONG dwProcessor,
  138. ULONG Flags
  139. )
  140. /*++
  141. Routine Description:
  142. Arguments:
  143. args -
  144. Return Value:
  145. None
  146. --*/
  147. {
  148. ULONG64 KiDispatcherReadyListHead;
  149. ULONG ListEntrySize, WaitListOpffset;
  150. ULONG result;
  151. LONG i;
  152. BOOLEAN ThreadDumped = FALSE;
  153. KiDispatcherReadyListHead = GetExpression( "nt!KiDispatcherReadyListHead" );
  154. if ( KiDispatcherReadyListHead ) {
  155. ListEntrySize = GetTypeSize("nt!_LIST_ENTRY");
  156. if (ListEntrySize == 0) {
  157. ListEntrySize = DBG_PTR_SIZE * 2;
  158. }
  159. GetFieldOffset("nt!_ETHREAD", "Tcb.WaitListEntry", &WaitListOpffset);
  160. for (i = MAXIMUM_PRIORITY-1; i >= 0 ; i -= 1 ) {
  161. ULONG64 Flink, Blink;
  162. if ( GetFieldValue( KiDispatcherReadyListHead + i*ListEntrySize,
  163. "nt!_LIST_ENTRY",
  164. "Flink",
  165. Flink) ) {
  166. dprintf(
  167. "Could not read contents of KiDispatcherReadyListHead at %08p [%ld]\n",
  168. (KiDispatcherReadyListHead + i * ListEntrySize), i
  169. );
  170. return E_INVALIDARG;
  171. }
  172. if (Flink != KiDispatcherReadyListHead+i*ListEntrySize) {
  173. ULONG64 ThreadEntry, ThreadFlink;
  174. dprintf("Ready Threads at priority %ld\n", i);
  175. for (ThreadEntry = Flink ;
  176. ThreadEntry != KiDispatcherReadyListHead+i*ListEntrySize ;
  177. ThreadEntry = ThreadFlink ) {
  178. ULONG64 ThreadBaseAddress = (ThreadEntry - WaitListOpffset);
  179. if ( GetFieldValue( ThreadBaseAddress,
  180. "nt!_ETHREAD",
  181. "Tcb.WaitListEntry.Flink",
  182. ThreadFlink) ) {
  183. dprintf("Could not read contents of thread %p\n", ThreadBaseAddress);
  184. }
  185. if(CheckControlC()) {
  186. return E_INVALIDARG;
  187. }
  188. DumpThread(dwProcessor," ", ThreadBaseAddress, Flags);
  189. ThreadDumped = TRUE;
  190. }
  191. } else {
  192. GetFieldValue( KiDispatcherReadyListHead + i*ListEntrySize,
  193. "nt!_LIST_ENTRY",
  194. "Blink",
  195. Blink);
  196. if (Flink != Blink) {
  197. dprintf("Ready linked list may to be corrupt...\n");
  198. }
  199. }
  200. }
  201. if (!ThreadDumped) {
  202. dprintf("No threads in READY state\n");
  203. }
  204. } else {
  205. dprintf("Could not determine address of KiDispatcherReadyListHead\n");
  206. return E_INVALIDARG;
  207. }
  208. return S_OK;
  209. }
  210. DECLARE_API( ready )
  211. /*++
  212. Routine Description:
  213. Arguments:
  214. args -
  215. Return Value:
  216. None
  217. --*/
  218. {
  219. DWORD Flags;
  220. ULONG dwProcessor=0;
  221. INIT_API();
  222. GetCurrentProcessor(Client, &dwProcessor, NULL);
  223. Flags = (ULONG)GetExpression(args);
  224. if (BuildNo <= 3598)
  225. {
  226. DumpReadyList_3598(dwProcessor, Flags);
  227. } else
  228. {
  229. DumpReadyList(dwProcessor, Flags);
  230. }
  231. EXIT_API();
  232. return S_OK;
  233. }