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.

326 lines
9.4 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. UNREFERENCED_PARAMETER (ContextRecord);
  167. UNREFERENCED_PARAMETER (PreviousMode);
  168. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
  169. (ExceptionRecord->NumberParameters > 0) &&
  170. (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) {
  171. return TRUE;
  172. } else {
  173. return FALSE;
  174. }
  175. }
  176. BOOLEAN
  177. KdpStub (
  178. IN PKTRAP_FRAME TrapFrame,
  179. IN PKEXCEPTION_FRAME ExceptionFrame,
  180. IN PEXCEPTION_RECORD ExceptionRecord,
  181. IN PCONTEXT ContextRecord,
  182. IN KPROCESSOR_MODE PreviousMode,
  183. IN BOOLEAN SecondChance
  184. )
  185. /*++
  186. Routine Description:
  187. This routine provides a kernel debugger stub routine to catch debug
  188. prints in a checked system when the kernel debugger is not active.
  189. Arguments:
  190. TrapFrame - Supplies a pointer to a trap frame that describes the
  191. trap.
  192. ExceptionFrame - Supplies a pointer to a exception frame that describes
  193. the trap.
  194. ExceptionRecord - Supplies a pointer to an exception record that
  195. describes the exception.
  196. ContextRecord - Supplies the context at the time of the exception.
  197. PreviousMode - Supplies the previous processor mode.
  198. SecondChance - Supplies a boolean value that determines whether this is
  199. the second chance (TRUE) that the exception has been raised.
  200. Return Value:
  201. A value of TRUE is returned if the exception is handled. Otherwise a
  202. value of FALSE is returned.
  203. --*/
  204. {
  205. UNREFERENCED_PARAMETER (TrapFrame);
  206. UNREFERENCED_PARAMETER (ExceptionFrame);
  207. UNREFERENCED_PARAMETER (PreviousMode);
  208. UNREFERENCED_PARAMETER (SecondChance);
  209. //
  210. // If the breakpoint is a debug print, then return TRUE. Otherwise,
  211. // return FALSE.
  212. //
  213. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
  214. (ExceptionRecord->NumberParameters > 0) &&
  215. ((ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_LOAD_SYMBOLS) ||
  216. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_UNLOAD_SYMBOLS) ||
  217. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_COMMAND_STRING) ||
  218. (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_PRINT))) {
  219. ContextRecord->Eip++;
  220. return TRUE;
  221. } else if (KdPitchDebugger == TRUE) {
  222. return FALSE;
  223. } else if (KdAutoEnableOnEvent &&
  224. KdPreviouslyEnabled &&
  225. !KdDebuggerEnabled) {
  226. // If there are multiple disables this may not reenable
  227. // the debugger. Check before calling the full trap routine.
  228. if (NT_SUCCESS(KdEnableDebugger()) &&
  229. KdDebuggerEnabled) {
  230. return KdpTrap(TrapFrame, ExceptionFrame, ExceptionRecord,
  231. ContextRecord, PreviousMode, SecondChance);
  232. } else {
  233. return KdpCheckTracePoint(ExceptionRecord, ContextRecord);
  234. }
  235. } else {
  236. return KdpCheckTracePoint(ExceptionRecord, ContextRecord);
  237. }
  238. }