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.

194 lines
5.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: queue.c
  7. //
  8. // Contents: Extension to dump the ExWorkerQueues
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // Coupling:
  15. //
  16. // Notes:
  17. //
  18. // History: 5-04-1998 benl Created
  19. //
  20. //----------------------------------------------------------------------------
  21. #include "precomp.h"
  22. #pragma hdrstop
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Function: DumpQueue
  26. //
  27. // Synopsis: Dumps a KQUEUE from its address
  28. //
  29. // Arguments: [iAddress] -- address of queue
  30. //
  31. // Returns:
  32. //
  33. // History: 4-29-1998 benl Created
  34. //
  35. // Notes: Assumes the items on the queue are of WORK_QUEUE_ITEM form
  36. // If this ever extended to dump arbitrary queues that assumption
  37. // will have to be dropped
  38. //
  39. //----------------------------------------------------------------------------
  40. VOID DumpQueue(ULONG64 iAddress, ULONG dwProcessor, ULONG Flags)
  41. {
  42. DWORD dwRead;
  43. UCHAR szSymbol[0x100];
  44. ULONG64 dwDisp;
  45. ULONG64 iNextAddr;
  46. ULONG64 iThread;
  47. ULONG64 pThread;
  48. ULONG CurrentCount, MaximumCount, Off;
  49. ULONG queueOffset;
  50. if (GetFieldValue(iAddress, "nt!_KQUEUE", "CurrentCount", CurrentCount))
  51. {
  52. dprintf("ReadMemory for queue at %p failed\n", iAddress );
  53. return;
  54. }
  55. GetFieldValue(iAddress, "nt!_KQUEUE", "MaximumCount",MaximumCount);
  56. // dprintf("EntryListHead: 0x%x 0x%x\n", Queue.EntryListHead.Flink,
  57. // Queue.EntryListHead.Blink);
  58. dprintf("( current = %u", CurrentCount);
  59. dprintf(" maximum = %u )\n", MaximumCount);
  60. if (CurrentCount >= MaximumCount) {
  61. dprintf("WARNING: active threads = maximum active threads in the queue. No new\n"
  62. " workitems schedulable in this queue until they finish or block.\n");
  63. }
  64. //print threads
  65. GetFieldValue(iAddress, "nt!_KQUEUE", "ThreadListHead.Flink", iThread);
  66. GetFieldOffset("nt!_KQUEUE", "ThreadListHead", &Off);
  67. GetFieldOffset("nt!_KTHREAD", "QueueListEntry", &queueOffset);
  68. while (iThread != iAddress + Off)
  69. {
  70. ULONG64 Flink;
  71. if (GetFieldValue(iThread, "nt!_LIST_ENTRY", "Flink", Flink))
  72. {
  73. dprintf("ReadMemory for threadqueuelist at %p failed\n", iThread);
  74. return;
  75. }
  76. pThread = iThread - queueOffset;
  77. DumpThread( dwProcessor, "", pThread, Flags);
  78. if (CheckControlC())
  79. {
  80. return;
  81. }
  82. iThread = (Flink);
  83. }
  84. dprintf("\n");
  85. //print queued items
  86. GetFieldValue(iAddress, "nt!_KQUEUE", "EntryListHead.Flink", iNextAddr);
  87. GetFieldOffset("nt!_KQUEUE", "EntryListHead", &Off);
  88. while (iNextAddr != iAddress + Off)
  89. {
  90. ULONG64 WorkerRoutine, Parameter;
  91. iThread = 0;
  92. if (GetFieldValue(iNextAddr, "nt!_WORK_QUEUE_ITEM", "WorkerRoutine",WorkerRoutine))
  93. {
  94. dprintf("ReadMemory for entry at %p failed\n", iNextAddr);
  95. return;
  96. }
  97. //try to get the function name
  98. GetSymbol(WorkerRoutine, szSymbol, &dwDisp);
  99. GetFieldValue(iNextAddr, "nt!_WORK_QUEUE_ITEM", "Parameter",Parameter);
  100. if (dwDisp) {
  101. dprintf("PENDING: WorkerRoutine %s+0x%p (%p) Parameter %p\n",
  102. szSymbol, WorkerRoutine, dwDisp, Parameter);
  103. } else {
  104. dprintf("PENDING: WorkerRoutine %s (%p) Parameter %p\n",
  105. szSymbol, WorkerRoutine, Parameter);
  106. }
  107. if (CheckControlC())
  108. {
  109. return;
  110. }
  111. GetFieldValue(iNextAddr, "nt!_WORK_QUEUE_ITEM", "List.Flink", iNextAddr);
  112. }
  113. if (!iThread) {
  114. dprintf("\n");
  115. }
  116. } // DumpQueue
  117. //+---------------------------------------------------------------------------
  118. //
  119. // Function: DECLARE_API
  120. //
  121. // Synopsis: Dump the ExWorkerQueues
  122. //
  123. // Arguments: [dexqueue] --
  124. //
  125. // Returns:
  126. //
  127. // History: 4-29-1998 benl Created
  128. //
  129. // Notes: Symbols better be correct or this will print garbage
  130. //
  131. //----------------------------------------------------------------------------
  132. DECLARE_API(exqueue)
  133. {
  134. ULONG64 iExQueue;
  135. ULONG Flags = 0;
  136. ULONG n;
  137. ULONG dwProcessor=0;
  138. INIT_API();
  139. GetCurrentProcessor(Client, &dwProcessor, NULL);
  140. //
  141. // Flags == 2 apes the default behavior of just printing out thread state.
  142. //
  143. if (args) {
  144. Flags = (ULONG)GetExpression(args);
  145. }
  146. iExQueue = GetExpression("NT!ExWorkerQueue");
  147. dprintf("Dumping ExWorkerQueue: %P\n\n", iExQueue);
  148. if (iExQueue)
  149. {
  150. if (!(Flags & 0xf0) || (Flags & 0x10)) {
  151. dprintf("**** Critical WorkQueue");
  152. DumpQueue(iExQueue, dwProcessor, Flags & 0xf);
  153. }
  154. if (!(Flags & 0xf0) || (Flags & 0x20)) {
  155. dprintf("**** Delayed WorkQueue");
  156. DumpQueue(iExQueue + GetTypeSize("nt!_EX_WORK_QUEUE"), dwProcessor, Flags & 0xf);
  157. }
  158. if (!(Flags & 0xf0) || (Flags & 0x40)) {
  159. dprintf("**** HyperCritical WorkQueue");
  160. DumpQueue(iExQueue + 2 * GetTypeSize("nt!_EX_WORK_QUEUE"), dwProcessor, Flags & 0xf);
  161. }
  162. }
  163. EXIT_API();
  164. return S_OK;
  165. } // DECLARE_API