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.

303 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. kdtrap.c
  5. Abstract:
  6. This module contains code to implement the target side of the portable
  7. kernel debugger.
  8. Author:
  9. Bryan M. Willman (bryanwi) 25-Sep-90
  10. Revision History:
  11. --*/
  12. #include "kdp.h"
  13. #pragma alloc_text(PAGEKD, KdpTrap)
  14. #pragma alloc_text(PAGEKD, KdIsThisAKdTrap)
  15. BOOLEAN
  16. KdpTrap (
  17. IN PKTRAP_FRAME TrapFrame,
  18. IN PKEXCEPTION_FRAME ExceptionFrame,
  19. IN PEXCEPTION_RECORD ExceptionRecord,
  20. IN PCONTEXT ContextRecord,
  21. IN KPROCESSOR_MODE PreviousMode,
  22. IN BOOLEAN SecondChance
  23. )
  24. /*++
  25. Routine Description:
  26. This routine is called whenever a exception is dispatched and the kernel
  27. debugger is active.
  28. Arguments:
  29. TrapFrame - Supplies a pointer to a trap frame that describes the
  30. trap.
  31. ExceptionFrame - Supplies a pointer to a exception frame that describes
  32. the trap.
  33. ExceptionRecord - Supplies a pointer to an exception record that
  34. describes the exception.
  35. ContextRecord - Supplies the context at the time of the exception.
  36. PreviousMode - Supplies the previous processor mode.
  37. SecondChance - Supplies a boolean value that determines whether this is
  38. the second chance (TRUE) that the exception has been raised.
  39. Return Value:
  40. A value of TRUE is returned if the exception is handled. Otherwise a
  41. value of FALSE is returned.
  42. --*/
  43. {
  44. BOOLEAN Completion = FALSE;
  45. BOOLEAN UnloadSymbols = FALSE;
  46. ULONG OldEip;
  47. //
  48. // Print, Prompt, Load symbols, Unload symbols, are all special
  49. // cases of STATUS_BREAKPOINT
  50. //
  51. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
  52. (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) {
  53. //
  54. // Switch on the breakpoint code.
  55. //
  56. OldEip = ContextRecord->Eip;
  57. switch (ExceptionRecord->ExceptionInformation[0]) {
  58. //
  59. // ExceptionInformation[1] - Address of the message.
  60. // ExceptionInformation[2] - Length of the message.
  61. // ContextRecord->Ebx - the Id of the calling component.
  62. // ContextRecord->Edi - the output importance level.
  63. //
  64. case BREAKPOINT_PRINT:
  65. ContextRecord->Eax = KdpPrint((ULONG)ContextRecord->Ebx,
  66. (ULONG)ContextRecord->Edi,
  67. (PCHAR)ExceptionRecord->ExceptionInformation[1],
  68. (USHORT)ExceptionRecord->ExceptionInformation[2],
  69. PreviousMode,
  70. TrapFrame,
  71. ExceptionFrame,
  72. &Completion);
  73. break;
  74. //
  75. // ExceptionInformation[1] - Address of the message.
  76. // ExceptionInformation[2] - Length of the message.
  77. // ContextRecord->Ebx - Address of the reply.
  78. // ContextRecord->Edi - Maximum length of reply.
  79. //
  80. case BREAKPOINT_PROMPT:
  81. ContextRecord->Eax = KdpPrompt((PCHAR)ExceptionRecord->ExceptionInformation[1],
  82. (USHORT)ExceptionRecord->ExceptionInformation[2],
  83. (PCHAR)ContextRecord->Ebx,
  84. (USHORT)ContextRecord->Edi,
  85. PreviousMode,
  86. TrapFrame,
  87. ExceptionFrame);
  88. Completion = TRUE;
  89. break;
  90. //
  91. // ExceptionInformation[1] is file name of new module.
  92. // ExceptionInformation[2] is a pointer to the symbol
  93. // information.
  94. //
  95. case BREAKPOINT_UNLOAD_SYMBOLS:
  96. UnloadSymbols = TRUE;
  97. //
  98. // Fall through
  99. //
  100. case BREAKPOINT_LOAD_SYMBOLS:
  101. KdpSymbol((PSTRING)ExceptionRecord->ExceptionInformation[1],
  102. (PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2],
  103. UnloadSymbols,
  104. PreviousMode,
  105. ContextRecord,
  106. TrapFrame,
  107. ExceptionFrame);
  108. Completion = TRUE;
  109. break;
  110. case BREAKPOINT_COMMAND_STRING:
  111. KdpCommandString((PSTRING)ExceptionRecord->ExceptionInformation[1],
  112. (PSTRING)ExceptionRecord->ExceptionInformation[2],
  113. PreviousMode,
  114. ContextRecord,
  115. TrapFrame,
  116. ExceptionFrame);
  117. Completion = TRUE;
  118. break;
  119. //
  120. // Unknown command
  121. //
  122. default:
  123. // return FALSE
  124. break;
  125. }
  126. //
  127. // If the kernel debugger did not update the EIP, then increment
  128. // past the breakpoint instruction.
  129. //
  130. if (ContextRecord->Eip == OldEip) {
  131. ContextRecord->Eip++;
  132. }
  133. } else {
  134. //
  135. // Report state change to the kernel debugger.
  136. //
  137. Completion = KdpReport(TrapFrame,
  138. ExceptionFrame,
  139. ExceptionRecord,
  140. ContextRecord,
  141. PreviousMode,
  142. SecondChance);
  143. }
  144. return Completion;
  145. }
  146. BOOLEAN
  147. KdIsThisAKdTrap (
  148. IN PEXCEPTION_RECORD ExceptionRecord,
  149. IN PCONTEXT ContextRecord,
  150. IN KPROCESSOR_MODE PreviousMode
  151. )
  152. /*++
  153. Routine Description:
  154. This routine is called whenever a user-mode exception occurs and
  155. it might be a kernel debugger exception (Like DbgPrint/DbgPrompt ).
  156. Arguments:
  157. ExceptionRecord - Supplies a pointer to an exception record that
  158. describes the exception.
  159. ContextRecord - Supplies the context at the time of the exception.
  160. PreviousMode - Supplies the previous processor mode.
  161. Return Value:
  162. A value of TRUE is returned if this is for the kernel debugger.
  163. Otherwise, a value of FALSE is returned.
  164. --*/
  165. {
  166. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
  167. (ExceptionRecord->NumberParameters > 0) &&
  168. (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) {
  169. return TRUE;
  170. } else {
  171. return FALSE;
  172. }
  173. }
  174. BOOLEAN
  175. KdpStub (
  176. IN PKTRAP_FRAME TrapFrame,
  177. IN PKEXCEPTION_FRAME ExceptionFrame,
  178. IN PEXCEPTION_RECORD ExceptionRecord,
  179. IN PCONTEXT ContextRecord,
  180. IN KPROCESSOR_MODE PreviousMode,
  181. IN BOOLEAN SecondChance
  182. )
  183. /*++
  184. Routine Description:
  185. This routine provides a kernel debugger stub routine to catch debug
  186. prints in a checked system when the kernel debugger is not active.
  187. Arguments:
  188. TrapFrame - Supplies a pointer to a trap frame that describes the
  189. trap.
  190. ExceptionFrame - Supplies a pointer to a exception frame that describes
  191. the trap.
  192. ExceptionRecord - Supplies a pointer to an exception record that
  193. describes the exception.
  194. ContextRecord - Supplies the context at the time of the exception.
  195. PreviousMode - Supplies the previous processor mode.
  196. SecondChance - Supplies a boolean value that determines whether this is
  197. the second chance (TRUE) that the exception has been raised.
  198. Return Value:
  199. A value of TRUE is returned if the exception is handled. Otherwise a
  200. value of FALSE is returned.
  201. --*/
  202. {
  203. //
  204. // If the breakpoint is a debug print, then return TRUE. Otherwise,
  205. // return FALSE.
  206. //
  207. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
  208. (ExceptionRecord->NumberParameters > 0) &&
  209. ((ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_LOAD_SYMBOLS) ||
  210. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_UNLOAD_SYMBOLS) ||
  211. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_PRINT))) {
  212. ContextRecord->Eip++;
  213. return TRUE;
  214. } else if (KdPitchDebugger == TRUE) {
  215. return FALSE;
  216. } else {
  217. return KdpCheckTracePoint(ExceptionRecord, ContextRecord);
  218. }
  219. }