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.

243 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. bugdump.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. David N. Cutler (davec) 6-Aug-1994
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "string.h"
  16. //
  17. // Declare storage for bug check dump buffer and component name.
  18. //
  19. #define BUFFER_SIZE (1 << 12)
  20. #define NAME_SIZE (1 << 5)
  21. ULONG DumpBuffer[BUFFER_SIZE / sizeof(ULONG)];
  22. UCHAR NameBuffer[NAME_SIZE + 1];
  23. DECLARE_API( bugdump )
  24. /*++
  25. Routine Description:
  26. Dump bug check callback data.
  27. Arguments:
  28. arg - Supplies the optional component name.
  29. Return Value:
  30. None.
  31. --*/
  32. {
  33. ULONG64 CallbackAddress;
  34. ULONG64 ComponentAddress;
  35. PUCHAR ComponentName;
  36. ULONG DataLength;
  37. PUCHAR DumpState;
  38. ULONG Limit;
  39. ULONG64 ListHead;
  40. ULONG Index;
  41. ULONG Inner;
  42. ULONG64 NextEntry;
  43. ULONG Result, Offset;
  44. //
  45. // If a componetn name name is specified, then only dump that components
  46. // data. Otherwise, dump the components data for all components that are
  47. // recorded in the bug check call back list.
  48. //
  49. if (args[0] != '\0') {
  50. ComponentName = (PUCHAR)&args[0];
  51. } else {
  52. ComponentName = NULL;
  53. }
  54. //
  55. // Get the address and contents of the bug check callback listhead.
  56. //
  57. dprintf("**** Dump of Bug Check Data ****\n");
  58. ListHead = GetNtDebuggerData(KeBugCheckCallbackListHead);
  59. if ((ListHead == 0) ||
  60. GetFieldValue(ListHead, "LIST_ENTRY", "Flink", NextEntry)) {
  61. //
  62. // The target build does not bug check callbacks.
  63. //
  64. dprintf("%08p: No bug check callback data available\n", ListHead);
  65. } else {
  66. GetFieldOffset("KBUGCHECK_CALLBACK_RECORD", "Entry", &Offset);
  67. //
  68. // Dump the specified bug check callback data.
  69. //
  70. while (NextEntry != ListHead) {
  71. //
  72. // Compute the address of the next callback record and read it.
  73. //
  74. CallbackAddress = NextEntry - Offset;
  75. if (GetFieldValue(CallbackAddress, "KBUGCHECK_CALLBACK_RECORD",
  76. "Entry.Flink", NextEntry)) {
  77. //
  78. // The target callback record could not be read.
  79. //
  80. dprintf("%08p: Bug check callback record could not be read\n",
  81. CallbackAddress);
  82. break;
  83. } else {
  84. ULONG State;
  85. //
  86. // Set the address of struct to be read
  87. //
  88. InitTypeRead(CallbackAddress, KBUGCHECK_CALLBACK_RECORD);
  89. //
  90. // Read the component name.
  91. //
  92. ComponentAddress = ReadField(Component);
  93. for (Index = 0; Index < NAME_SIZE; Index += 1) {
  94. if (ReadMemory(ComponentAddress,
  95. &NameBuffer[Index],
  96. sizeof(UCHAR),
  97. &Result) == FALSE) {
  98. NameBuffer[Index] = '\0';
  99. }
  100. ComponentAddress += 1;
  101. if (NameBuffer[Index] == '\0') {
  102. break;
  103. }
  104. }
  105. NameBuffer[Index] = '\0';
  106. //
  107. // If a component name is specified, then compare the
  108. // component with the specified name. If the component
  109. // name does not match, then continue with the next
  110. // entry in the list.
  111. //
  112. if (ComponentName != NULL) {
  113. if (_stricmp(ComponentName, &NameBuffer[0]) != 0) {
  114. continue;
  115. }
  116. }
  117. //
  118. // Either all bug callback records are being dumped or the
  119. // specified component has been found. Dump the contents of
  120. // the dump buffer, if the state of the callback record is
  121. // not inserted.
  122. //
  123. dprintf(" Dumping data for component %s \n", &NameBuffer[0]);
  124. State = (ULONG) ReadField(State);
  125. if (State == BufferInserted) {
  126. dprintf(" No bug check dump data available\n\n");
  127. } else {
  128. if (State == BufferStarted) {
  129. DumpState = "Dump started/not finished";
  130. } else if (State == BufferFinished) {
  131. DumpState = "Dump started/finished";
  132. } else {
  133. DumpState = "Dump started/not completed";
  134. }
  135. dprintf(" Buffer state - %s\n\n", DumpState);
  136. DataLength = (ULONG) ReadField(Length);
  137. if (DataLength > BUFFER_SIZE) {
  138. DataLength = BUFFER_SIZE;
  139. }
  140. RtlZeroMemory(&DumpBuffer[0], BUFFER_SIZE);
  141. if (ReadMemory(ReadField(Buffer),
  142. &DumpBuffer[0],
  143. DataLength,
  144. &Result) == FALSE) {
  145. dprintf("%08lx: Bug check dump data could not be read\n",
  146. Result);
  147. } else {
  148. //
  149. // Display bug check data.
  150. //
  151. DataLength = (DataLength + sizeof(ULONG) - 1) / sizeof(ULONG);
  152. for (Index = 0; Index < DataLength; Index += 4) {
  153. dprintf("%08lx", Index * 4);
  154. Limit = Index + 4;
  155. if (Limit > DataLength) {
  156. Limit = DataLength;
  157. }
  158. for (Inner = Index; Inner < Limit; Inner += 1) {
  159. dprintf(" %08lx", DumpBuffer[Inner]);
  160. }
  161. dprintf("\n");
  162. }
  163. dprintf("\n");
  164. }
  165. }
  166. if (ComponentName != NULL) {
  167. break;
  168. }
  169. }
  170. }
  171. }
  172. return S_OK;
  173. }