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.

337 lines
9.5 KiB

  1. /*++
  2. Copyright (c) 2000 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. David N. Cutler (davec) 14-May-2000
  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. ULONG64 OldRip;
  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. OldRip = ContextRecord->Rip;
  57. switch (ExceptionRecord->ExceptionInformation[0]) {
  58. //
  59. // Print a debug string.
  60. //
  61. // Arguments:
  62. //
  63. // rcx - Supplies a pointer to an output string buffer.
  64. // dx - Supplies the length of the output string buffer.
  65. // r8d - Supplies the Id of the calling component.
  66. // r9d - Supplies the output filter level.
  67. //
  68. case BREAKPOINT_PRINT:
  69. ContextRecord->Rax = KdpPrint((ULONG)ContextRecord->R8,
  70. (ULONG)ContextRecord->R9,
  71. (PCHAR)ContextRecord->Rcx,
  72. (USHORT)ContextRecord->Rdx,
  73. PreviousMode,
  74. TrapFrame,
  75. ExceptionFrame,
  76. &Completion);
  77. break;
  78. //
  79. // Print a debug prompt string, then input a string.
  80. //
  81. // Arguments:
  82. //
  83. // rcx - Supplies a pointer to an output string buffer.
  84. // dx - Supplies the length of the output string buffer.
  85. // r8 - Supplies a pointer to an input string buffer.
  86. // r9w - Supplies the length of the input string bufffer.
  87. //
  88. case BREAKPOINT_PROMPT:
  89. ContextRecord->Rax = KdpPrompt((PCHAR)ContextRecord->Rcx,
  90. (USHORT)ContextRecord->Rdx,
  91. (PCHAR)ContextRecord->R8,
  92. (USHORT)ContextRecord->R9,
  93. PreviousMode,
  94. TrapFrame,
  95. ExceptionFrame);
  96. Completion = TRUE;
  97. break;
  98. //
  99. // Load the symbolic information for an image.
  100. //
  101. // Arguments:
  102. //
  103. // rcx - Supplies a pointer to a filename string descriptor.
  104. // rdx - Supplies the base address of the image.
  105. //
  106. case BREAKPOINT_UNLOAD_SYMBOLS:
  107. UnloadSymbols = TRUE;
  108. //
  109. // Fall through
  110. //
  111. case BREAKPOINT_LOAD_SYMBOLS:
  112. KdpSymbol((PSTRING)ContextRecord->Rcx,
  113. (PKD_SYMBOLS_INFO)ContextRecord->Rdx,
  114. UnloadSymbols,
  115. PreviousMode,
  116. ContextRecord,
  117. TrapFrame,
  118. ExceptionFrame);
  119. Completion = TRUE;
  120. break;
  121. case BREAKPOINT_COMMAND_STRING:
  122. KdpCommandString((PSTRING)ContextRecord->Rcx,
  123. (PSTRING)ContextRecord->Rdx,
  124. PreviousMode,
  125. ContextRecord,
  126. TrapFrame,
  127. ExceptionFrame);
  128. Completion = TRUE;
  129. break;
  130. //
  131. // Unknown command
  132. //
  133. default:
  134. break;
  135. }
  136. //
  137. // If the kernel debugger did not update RIP, then increment
  138. // past the breakpoint instruction.
  139. //
  140. if (ContextRecord->Rip == OldRip) {
  141. ContextRecord->Rip += 1;
  142. }
  143. } else {
  144. //
  145. // Report state change to the kernel debugger.
  146. //
  147. Completion = KdpReport(TrapFrame,
  148. ExceptionFrame,
  149. ExceptionRecord,
  150. ContextRecord,
  151. PreviousMode,
  152. SecondChance);
  153. }
  154. return Completion;
  155. }
  156. BOOLEAN
  157. KdIsThisAKdTrap (
  158. IN PEXCEPTION_RECORD ExceptionRecord,
  159. IN PCONTEXT ContextRecord,
  160. IN KPROCESSOR_MODE PreviousMode
  161. )
  162. /*++
  163. Routine Description:
  164. This routine is called whenever a user mode exception occurs and
  165. it might be a kernel debugger exception (e.g., DbgPrint/DbgPrompt).
  166. Arguments:
  167. ExceptionRecord - Supplies a pointer to an exception record that
  168. describes the exception.
  169. ContextRecord - Supplies the context at the time of the exception.
  170. PreviousMode - Supplies the previous processor mode.
  171. Return Value:
  172. A value of TRUE is returned if this is for the kernel debugger.
  173. Otherwise, a value of FALSE is returned.
  174. --*/
  175. {
  176. UNREFERENCED_PARAMETER(ContextRecord);
  177. UNREFERENCED_PARAMETER(PreviousMode);
  178. if (((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) ||
  179. (ExceptionRecord->ExceptionCode == STATUS_WX86_BREAKPOINT)) &&
  180. (ExceptionRecord->NumberParameters > 0) &&
  181. (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) {
  182. return TRUE;
  183. } else {
  184. return FALSE;
  185. }
  186. }
  187. BOOLEAN
  188. KdpStub (
  189. IN PKTRAP_FRAME TrapFrame,
  190. IN PKEXCEPTION_FRAME ExceptionFrame,
  191. IN PEXCEPTION_RECORD ExceptionRecord,
  192. IN PCONTEXT ContextRecord,
  193. IN KPROCESSOR_MODE PreviousMode,
  194. IN BOOLEAN SecondChance
  195. )
  196. /*++
  197. Routine Description:
  198. This routine provides a kernel debugger stub routine to catch debug
  199. prints in a checked system when the kernel debugger is not active.
  200. Arguments:
  201. TrapFrame - Supplies a pointer to a trap frame that describes the
  202. trap.
  203. ExceptionFrame - Supplies a pointer to a exception frame that describes
  204. the trap.
  205. ExceptionRecord - Supplies a pointer to an exception record that
  206. describes the exception.
  207. ContextRecord - Supplies the context at the time of the exception.
  208. PreviousMode - Supplies the previous processor mode.
  209. SecondChance - Supplies a boolean value that determines whether this is
  210. the second chance (TRUE) that the exception has been raised.
  211. Return Value:
  212. A value of TRUE is returned if the exception is handled. Otherwise a
  213. value of FALSE is returned.
  214. --*/
  215. {
  216. UNREFERENCED_PARAMETER(TrapFrame);
  217. UNREFERENCED_PARAMETER(ExceptionFrame);
  218. UNREFERENCED_PARAMETER(PreviousMode);
  219. UNREFERENCED_PARAMETER(SecondChance);
  220. //
  221. // If the breakpoint is a debug print or load/unload symbols, then return
  222. // TRUE. Otherwise, return FALSE.
  223. //
  224. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
  225. (ExceptionRecord->NumberParameters > 0) &&
  226. ((ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_LOAD_SYMBOLS) ||
  227. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_UNLOAD_SYMBOLS) ||
  228. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_COMMAND_STRING) ||
  229. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_PRINT))) {
  230. ContextRecord->Rip += 1;
  231. return TRUE;
  232. } else if (!KdPitchDebugger &&
  233. KdAutoEnableOnEvent &&
  234. KdPreviouslyEnabled &&
  235. !KdDebuggerEnabled) {
  236. // If there are multiple disables this may not reenable
  237. // the debugger. Check before calling the full trap routine.
  238. if (NT_SUCCESS(KdEnableDebugger()) &&
  239. KdDebuggerEnabled) {
  240. return KdpTrap(TrapFrame, ExceptionFrame, ExceptionRecord,
  241. ContextRecord, PreviousMode, SecondChance);
  242. } else {
  243. return FALSE;
  244. }
  245. } else {
  246. return FALSE;
  247. }
  248. }