Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

kdtrap.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 Copyright (c) 1992-1993 Digital Equipment Corporation 00005 00006 Module Name: 00007 00008 kdtrap.c 00009 00010 Abstract: 00011 00012 This module contains code to implement the target side of the portable 00013 kernel debugger. 00014 00015 Author: 00016 00017 David N. Cutler 27-July-1990 00018 Joe Notarangelo 24-June-1992 (ALPHA version) 00019 00020 Revision History: 00021 00022 --*/ 00023 00024 #include "kdp.h" 00025 00026 00027 BOOLEAN 00028 KdpTrap ( 00029 IN PKTRAP_FRAME TrapFrame, 00030 IN PKEXCEPTION_FRAME ExceptionFrame, 00031 IN PEXCEPTION_RECORD ExceptionRecord, 00032 IN PCONTEXT ContextRecord, 00033 IN KPROCESSOR_MODE PreviousMode, 00034 IN BOOLEAN SecondChance 00035 ) 00036 00037 /*++ 00038 00039 Routine Description: 00040 00041 This routine is called whenever a exception is dispatched and the kernel 00042 debugger is active. 00043 00044 Arguments: 00045 00046 TrapFrame - Supplies a pointer to a trap frame that describes the 00047 trap. 00048 00049 ExceptionFrame - Supplies a pointer to a exception frame that describes 00050 the trap. 00051 00052 ExceptionRecord - Supplies a pointer to an exception record that 00053 describes the exception. 00054 00055 ContextRecord - Supplies the context at the time of the exception. 00056 00057 PreviousMode - Supplies the previous processor mode. 00058 00059 SecondChance - Supplies a boolean value that determines whether this is 00060 the second chance (TRUE) that the exception has been raised. 00061 00062 Return Value: 00063 00064 A value of TRUE is returned if the exception is handled. Otherwise a 00065 value of FALSE is returned. 00066 00067 --*/ 00068 00069 { 00070 00071 BOOLEAN Completion; 00072 BOOLEAN Enable; 00073 BOOLEAN UnloadSymbols = FALSE; 00074 STRING Input; 00075 ULONGLONG OldFir; 00076 STRING Output; 00077 PKPRCB Prcb; 00078 00079 // 00080 // Enter debugger and synchronize processor execution. 00081 // 00082 00083 // 00084 // If this is a breakpoint instruction, then check to determine if is 00085 // an internal command. 00086 // 00087 00088 if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && 00089 (ExceptionRecord->ExceptionInformation[0] >= DEBUG_PRINT_BREAKPOINT)){ 00090 00091 // 00092 // Switch on the breakpoint code. 00093 // 00094 00095 switch (ExceptionRecord->ExceptionInformation[0]) { 00096 00097 // 00098 // Print a debug string. 00099 // 00100 // Arguments: 00101 // 00102 // a0 - Supplies a pointer to an output string buffer. 00103 // a1 - Supplies the length of the output string buffer. 00104 // 00105 00106 case DEBUG_PRINT_BREAKPOINT: 00107 00108 ContextRecord->Fir += 4; 00109 Output.Buffer = (PCHAR)ContextRecord->IntA0; 00110 Output.Length = (USHORT)ContextRecord->IntA1; 00111 00112 KdLogDbgPrint(&Output); 00113 00114 if (KdDebuggerNotPresent == FALSE) { 00115 00116 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00117 if (KdpPrintString(&Output)) { 00118 ContextRecord->IntV0 = (ULONG)STATUS_BREAKPOINT; 00119 } else { 00120 ContextRecord->IntV0 = (ULONG)STATUS_SUCCESS; 00121 } 00122 KdExitDebugger(Enable); 00123 00124 } else { 00125 ContextRecord->IntV0 = (ULONG)STATUS_DEVICE_NOT_CONNECTED; 00126 } 00127 00128 return TRUE; 00129 00130 00131 // 00132 // Stop in the debugger 00133 // 00134 // As this is not a normal breakpoint we must increment the 00135 // context past the breakpoint instruction 00136 // 00137 00138 case BREAKIN_BREAKPOINT: 00139 00140 ContextRecord->Fir += 4; 00141 break; 00142 00143 // 00144 // Print a debug prompt string, then input a string. 00145 // 00146 // a0 - Supplies a pointer to an output string buffer. 00147 // a1 - Supplies the length of the output string buffer.. 00148 // a2 - supplies a pointer to an input string buffer. 00149 // a3 - Supplies the length of the input string bufffer. 00150 // 00151 00152 case DEBUG_PROMPT_BREAKPOINT: 00153 00154 ContextRecord->Fir += 4; 00155 Output.Buffer = (PCHAR)ContextRecord->IntA0; 00156 Output.Length = (USHORT)ContextRecord->IntA1; 00157 Input.Buffer = (PCHAR)ContextRecord->IntA2; 00158 Input.MaximumLength = (USHORT)ContextRecord->IntA3; 00159 00160 KdLogDbgPrint(&Output); 00161 00162 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00163 00164 KdpPromptString(&Output, &Input); 00165 00166 ContextRecord->IntV0 = Input.Length; 00167 00168 KdExitDebugger(Enable); 00169 return TRUE; 00170 00171 // 00172 // Load the symbolic information for an image. 00173 // 00174 // Arguments: 00175 // 00176 // a0 - Supplies a pointer to an output string descriptor. 00177 // a1 - Supplies a the base address of the image. 00178 // a2 - Supplies the current process id. 00179 // 00180 00181 case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT: 00182 00183 UnloadSymbols = TRUE; 00184 00185 // 00186 // Fall through 00187 // 00188 00189 case DEBUG_LOAD_SYMBOLS_BREAKPOINT: 00190 00191 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00192 Prcb = KeGetCurrentPrcb(); 00193 OldFir = ContextRecord->Fir; 00194 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, 00195 ContextRecord, 00196 sizeof(CONTEXT)); 00197 00198 if (KdDebuggerNotPresent == FALSE) { 00199 00200 KdpReportLoadSymbolsStateChange((PSTRING)ContextRecord->IntA0, 00201 (PKD_SYMBOLS_INFO) ContextRecord->IntA1, 00202 UnloadSymbols, 00203 &Prcb->ProcessorState.ContextFrame); 00204 00205 } 00206 00207 RtlCopyMemory(ContextRecord, 00208 &Prcb->ProcessorState.ContextFrame, 00209 sizeof(CONTEXT)); 00210 00211 KdExitDebugger(Enable); 00212 00213 // 00214 // If the kernel debugger did not update the FIR, then increment 00215 // past the breakpoint instruction. 00216 // 00217 00218 if (ContextRecord->Fir == OldFir) { 00219 ContextRecord->Fir += 4; 00220 } 00221 00222 return TRUE; 00223 00224 // 00225 // Unknown internal command. 00226 // 00227 00228 default: 00229 00230 break; 00231 } 00232 } 00233 00234 // 00235 // Report state change to kernel debugger on host machine. 00236 // 00237 00238 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00239 Prcb = KeGetCurrentPrcb(); 00240 00241 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, 00242 ContextRecord, 00243 sizeof (CONTEXT)); 00244 00245 Completion = KdpReportExceptionStateChange(ExceptionRecord, 00246 &Prcb->ProcessorState.ContextFrame, 00247 SecondChance); 00248 00249 RtlCopyMemory(ContextRecord, 00250 &Prcb->ProcessorState.ContextFrame, 00251 sizeof(CONTEXT)); 00252 00253 KdExitDebugger(Enable); 00254 00255 KdpControlCPressed = FALSE; 00256 00257 // 00258 // Always return TRUE if this is the first chance to handle the 00259 // exception. Otherwise, return the completion status of the 00260 // state change reporting. 00261 // 00262 00263 if( SecondChance ){ 00264 return Completion; 00265 } else { 00266 return TRUE; 00267 } 00268 } 00269 00270 BOOLEAN 00271 KdIsThisAKdTrap ( 00272 IN PEXCEPTION_RECORD ExceptionRecord, 00273 IN PCONTEXT ContextRecord, 00274 IN KPROCESSOR_MODE PreviousMode 00275 ) 00276 00277 /*++ 00278 00279 Routine Description: 00280 00281 This routine is called whenever a user-mode exception occurs and 00282 it might be a kernel debugger exception (Like DbgPrint/DbgPrompt ). 00283 00284 Arguments: 00285 00286 ExceptionRecord - Supplies a pointer to an exception record that 00287 describes the exception. 00288 00289 ContextRecord - Supplies the context at the time of the exception. 00290 00291 PreviousMode - Supplies the previous processor mode. 00292 00293 Return Value: 00294 00295 A value of TRUE is returned if this is for the kernel debugger. 00296 Otherwise, a value of FALSE is returned. 00297 00298 --*/ 00299 00300 { 00301 00302 // 00303 // Isolate the breakpoint code from the breakpoint instruction which 00304 // is stored by the exception dispatch code in the information field 00305 // of the exception record. 00306 // 00307 00308 // 00309 // Switch on the breakpoint code. 00310 // 00311 00312 switch (ExceptionRecord->ExceptionInformation[0]) { 00313 00314 // 00315 // Kernel breakpoint code. 00316 // 00317 00318 case KERNEL_BREAKPOINT: 00319 case BREAKIN_BREAKPOINT: 00320 #if DEVL 00321 return TRUE; 00322 #else 00323 if (PreviousMode == KernelMode) { 00324 return TRUE; 00325 00326 } else { 00327 return FALSE; 00328 } 00329 #endif 00330 00331 // 00332 // Debug print code. 00333 // 00334 00335 case DEBUG_PRINT_BREAKPOINT: 00336 return TRUE; 00337 00338 // 00339 // Debug prompt code. 00340 // 00341 case DEBUG_PROMPT_BREAKPOINT: 00342 return TRUE; 00343 00344 // 00345 // Debug stop code. 00346 // 00347 00348 case DEBUG_STOP_BREAKPOINT: 00349 #if DEVL 00350 return TRUE; 00351 #else 00352 if (PreviousMode == KernelMode) { 00353 return TRUE; 00354 00355 } else { 00356 return FALSE; 00357 } 00358 #endif 00359 00360 // 00361 // Debug load symbols code. 00362 // 00363 00364 case DEBUG_LOAD_SYMBOLS_BREAKPOINT: 00365 if (PreviousMode == KernelMode) { 00366 return TRUE; 00367 00368 } else { 00369 return FALSE; 00370 } 00371 00372 // 00373 // Debug unload symbols code. 00374 // 00375 00376 case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT: 00377 if (PreviousMode == KernelMode) { 00378 return TRUE; 00379 00380 } else { 00381 return FALSE; 00382 } 00383 // 00384 // All other codes. 00385 // 00386 00387 default: 00388 return FALSE; 00389 } 00390 } 00391 00392 BOOLEAN 00393 KdpStub ( 00394 IN PKTRAP_FRAME TrapFrame, 00395 IN PKEXCEPTION_FRAME ExceptionFrame, 00396 IN PEXCEPTION_RECORD ExceptionRecord, 00397 IN PCONTEXT ContextRecord, 00398 IN KPROCESSOR_MODE PreviousMode, 00399 IN BOOLEAN SecondChance 00400 ) 00401 00402 /*++ 00403 00404 Routine Description: 00405 00406 This routine provides a kernel debugger stub routine that catchs debug 00407 prints in checked systems when the kernel debugger is not active. 00408 00409 Arguments: 00410 00411 TrapFrame - Supplies a pointer to a trap frame that describes the 00412 trap. 00413 00414 ExceptionFrame - Supplies a pointer to a exception frame that describes 00415 the trap. 00416 00417 ExceptionRecord - Supplies a pointer to an exception record that 00418 describes the exception. 00419 00420 ContextRecord - Supplies the context at the time of the exception. 00421 00422 PreviousMode - Supplies the previous processor mode. 00423 00424 SecondChance - Supplies a boolean value that determines whether this is 00425 the second chance (TRUE) that the exception has been raised. 00426 00427 Return Value: 00428 00429 A value of TRUE is returned if the exception is handled. Otherwise a 00430 value of FALSE is returned. 00431 00432 --*/ 00433 00434 { 00435 00436 ULONG_PTR BreakpointCode; 00437 00438 // 00439 // Isolate the breakpoint code from the breakpoint instruction which 00440 // is stored by the exception dispatch code in the information field 00441 // of the exception record. 00442 // 00443 00444 BreakpointCode = ExceptionRecord->ExceptionInformation[0]; 00445 00446 // 00447 // If the breakpoint is a debug print, debug load symbols, or debug 00448 // unload symbols, then return TRUE. Otherwise, return FALSE; 00449 // 00450 00451 if ((BreakpointCode == DEBUG_PRINT_BREAKPOINT) || 00452 (BreakpointCode == DEBUG_LOAD_SYMBOLS_BREAKPOINT) || 00453 (BreakpointCode == DEBUG_UNLOAD_SYMBOLS_BREAKPOINT) || 00454 (BreakpointCode == KERNEL_BREAKPOINT)) { 00455 ContextRecord->Fir += 4; 00456 return TRUE; 00457 } else { 00458 if ( (BreakpointCode == DEBUG_STOP_BREAKPOINT) && 00459 (PreviousMode == KernelMode) ){ 00460 ContextRecord->Fir += 4; 00461 return TRUE; 00462 } else { 00463 return FALSE; 00464 } 00465 } 00466 }

Generated on Sat May 15 19:40:35 2004 for test by doxygen 1.3.7