test: 4/i386/kdtrap.c File Reference

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

# kdtrap.c File Reference

`#include "kdp.h"`

Go to the source code of this file.

## Functions

PUCHAR | KdpCopyDataToStack (PUCHAR, ULONG)
BOOLEAN | KdpTrap (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)
BOOLEAN | KdIsThisAKdTrap (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode)
BOOLEAN | KdpCheckTracePoint (IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord)
VOID | SaveSymLoad (IN PSTRING PathName, IN PVOID BaseOfDll, IN LONG ProcessId, IN BOOLEAN UnloadSymbols)
BOOLEAN | KdpStub (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)

## Function Documentation

BOOLEAN KdIsThisAKdTrap | ( | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PCONTEXT | ContextRecord,
|  | IN KPROCESSOR_MODE | PreviousMode
| ) |

Definition at line 406 of file 4/i386/kdtrap.c.

References BREAKPOINT_BREAK, FALSE, and TRUE.

    00414                    :
    00415
    00416     This routine is called whenever a user-mode exception occurs and
    00417     it might be a kernel debugger exception (Like DbgPrint/DbgPrompt ).
    00418
    00419 Arguments:
    00420
    00421     ExceptionRecord - Supplies a pointer to an exception record that
    00422         describes the exception.
    00423
    00424     ContextRecord - Supplies the context at the time of the exception.
    00425
    00426     PreviousMode - Supplies the previous processor mode.
    00427
    00428 Return Value:
    00429
    00430     A value of TRUE is returned if this is for the kernel debugger.
    00431     Otherwise, a value of FALSE is returned.
    00432
    00433 --*/
    00434
    00435 {
    00436     if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
    00437         (ExceptionRecord->NumberParameters > 0) &&
    00438         (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) {
    00439
    00440         return TRUE;
    00441     } else {
    00442         return FALSE;
    00443     }
    00444     UNREFERENCED_PARAMETER(ContextRecord);
    00445 }

BOOLEAN KdpCheckTracePoint | ( | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN OUT PCONTEXT | ContextRecord
| ) |

| Referenced by KdpReportExceptionStateChange(), and KdpStub().

PUCHAR KdpCopyDataToStack | ( | PUCHAR | ,
|  | ULONG |
| ) |

| Referenced by KdpTrap().

BOOLEAN KdpStub | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PCONTEXT | ContextRecord,
|  | IN KPROCESSOR_MODE | PreviousMode,
|  | IN BOOLEAN | SecondChance
| ) |

Definition at line 462 of file 4/i386/kdtrap.c.

References FALSE, KdpCheckTracePoint(), KdPitchDebugger, and TRUE.

    00473                    :
    00474
    00475     This routine provides a kernel debugger stub routine to catch debug
    00476     prints in a checked system when the kernel debugger is not active.
    00477
    00478 Arguments:
    00479
    00480     TrapFrame - Supplies a pointer to a trap frame that describes the
    00481         trap.
    00482
    00483     ExceptionFrame - Supplies a pointer to a exception frame that describes
    00484         the trap.
    00485
    00486     ExceptionRecord - Supplies a pointer to an exception record that
    00487         describes the exception.
    00488
    00489     ContextRecord - Supplies the context at the time of the exception.
    00490
    00491     PreviousMode - Supplies the previous processor mode.
    00492
    00493     SecondChance - Supplies a boolean value that determines whether this is
    00494         the second chance (TRUE) that the exception has been raised.
    00495
    00496 Return Value:
    00497
    00498     A value of TRUE is returned if the exception is handled. Otherwise a
    00499     value of FALSE is returned.
    00500
    00501 --*/
    00502
    00503 {
    00504     PULONG  SymbolArgs;
    00505     //
    00506     // If the breakpoint is a debug print, then return TRUE. Otherwise,
    00507     // return FALSE.
    00508     //
    00509
    00510     if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
    00511         (ExceptionRecord->NumberParameters > 0) &&
    00512         ((ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_LOAD_SYMBOLS)||
    00513          (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_UNLOAD_SYMBOLS)||
    00514          (ExceptionRecord->ExceptionInformation[0] == BREAKPOINT_PRINT))) {
    00515
    00516         ContextRecord->Eip++;
    00517         return(TRUE);
    00518     } else if (KdPitchDebugger == TRUE) {
    00519         return(FALSE);
    00520     } else {
    00521         return(KdpCheckTracePoint(ExceptionRecord,ContextRecord));
    00522     }
    00523 }
    }

BOOLEAN KdpTrap | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PCONTEXT | ContextRecord,
|  | IN KPROCESSOR_MODE | PreviousMode,
|  | IN BOOLEAN | SecondChance
| ) |

Definition at line 38 of file 4/i386/kdtrap.c.

References BREAKPOINT_BREAK, Buffer, CHAR, EXCEPTION_EXECUTE_HANDLER, FALSE, KdDebuggerNotPresent, KdEnterDebugger(), KdExitDebugger(), KdLogDbgPrint(), KdpControlCPressed, KdpCopyDataToStack(), KdpPrintString(), KdpPromptString(), KdpQuickMoveMemory(), KdpReportExceptionStateChange(), KdpReportLoadSymbolsStateChange(), KeGetCurrentPrcb, KernelMode, KiRestoreProcessorControlState(), KiSaveProcessorControlState(), NT_SUCCESS, NtGlobalFlag, ProbeForRead, ProbeForWrite(), String, TRUE, and UserMode.

    00049                    :
    00050
    00051     This routine is called whenever a exception is dispatched and the kernel
    00052     debugger is active.
    00053
    00054 Arguments:
    00055
    00056     TrapFrame - Supplies a pointer to a trap frame that describes the
    00057         trap.
    00058
    00059     ExceptionFrame - Supplies a pointer to a exception frame that describes
    00060         the trap.
    00061
    00062     ExceptionRecord - Supplies a pointer to an exception record that
    00063         describes the exception.
    00064
    00065     ContextRecord - Supplies the context at the time of the exception.
    00066
    00067     PreviousMode - Supplies the previous processor mode.
    00068
    00069     SecondChance - Supplies a boolean value that determines whether this is
    00070         the second chance (TRUE) that the exception has been raised.
    00071
    00072 Return Value:
    00073
    00074     A value of TRUE is returned if the exception is handled. Otherwise a
    00075     value of FALSE is returned.
    00076
    00077 --*/
    00078
    00079 {
    00080
    00081     BOOLEAN Completion = FALSE;
    00082     BOOLEAN Enable;
    00083     BOOLEAN UnloadSymbols = FALSE;
    00084     ULONG   RetValue;
    00085     STRING  String, ReplyString;
    00086     PUCHAR  Buffer;
    00087     PKD_SYMBOLS_INFO SymbolInfo;
    00088     PVOID   SavedEsp;
    00089     PKPRCB  Prcb;
    00090     ULONG   OldEip;
    00091
    00092     _asm {
    00093         //
    00094         // Save esp on ebp frame so c-runtime registers are restored correctly
    00095         //
    00096
    00097         mov     SavedEsp, esp
    00098     }
    00099
    00100     //
    00101     // Print, Prompt, Load symbols, Unload symbols, are all special
    00102     // cases of STATUS_BREAKPOINT
    00103     //
    00104
    00105     if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
    00106         (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK)) {
    00107
    00108         //
    00109         // We have one of the support functions.
    00110         //
    00111
    00112         if (KdDebuggerNotPresent  &&
    00113             ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_PROMPT) {
    00114             ContextRecord->Eip++;
    00115             return(TRUE);
    00116         }
    00117
    00118
    00119         //
    00120         // Since some of these functions can be entered from user mode,
    00121         // we hold off entering the debugger until the user mode buffers
    00122         // are copied.  (Because they may not be present in memory, and
    00123         // they must be paged in before we raise Irql to the
    00124         // Highest level.)
    00125         //
    00126         //
    00127
    00128         OldEip = ContextRecord->Eip;
    00129
    00130         switch (ExceptionRecord->ExceptionInformation[0]) {
    00131
    00132             //
    00133             //  ExceptionInformation[1] is PSTRING to print
    00134             //
    00135
    00136             case BREAKPOINT_PRINT:
    00137
    00138                 if (PreviousMode == UserMode) {
    00139
    00140                     EXCEPTION_RECORD exr;
    00141                     //
    00142                     // Move user mode parameters to kernel stack
    00143                     //
    00144
    00145                     try {
    00146                         String = *((PSTRING)ExceptionRecord->ExceptionInformation[1]);
    00147                         if (String.Length > 512) {
    00148                             break;
    00149                         }
    00150                         ProbeForRead(String.Buffer, String.Length, sizeof(UCHAR));
    00151                         String.Buffer =
    00152                             KdpCopyDataToStack(String.Buffer, String.Length);
    00153
    00154                     } except ((exr = *((GetExceptionInformation())->ExceptionRecord), EXCEPTION_EXECUTE_HANDLER)) {
    00155
    00156                         //
    00157                         // If an exception occurs then don't handle
    00158                         // this DebugService request.
    00159                         //
    00160
    00161                         break;
    00162                     }
    00163
    00164                 } else {
    00165                     String = *((PSTRING)ExceptionRecord->ExceptionInformation[1]);
    00166                 }
    00167
    00168                 KdLogDbgPrint(&String);
    00169
    00170                 if ((NtGlobalFlag & FLG_DISABLE_DBGPRINT) == 0) {
    00171                     Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    00172                     if (KdpPrintString(&String)) {
    00173                         ContextRecord->Eax = (ULONG)(STATUS_BREAKPOINT);
    00174                     } else {
    00175                         ContextRecord->Eax = STATUS_SUCCESS;
    00176                     }
    00177                     KdExitDebugger(Enable);
    00178                 }
    00179
    00180                 Completion = TRUE;
    00181                 break;
    00182
    00183             //
    00184             //  ExceptionInformation[1] is prompt string,
    00185             //  ExceptionInformation[2] is return string
    00186             //
    00187
    00188             case BREAKPOINT_PROMPT:
    00189                 if (PreviousMode == UserMode) {
    00190
    00191                     //
    00192                     // Move user mode parameters to kernel stack
    00193                     //
    00194
    00195
    00196                     try {
    00197                         String = *((PSTRING)ExceptionRecord->ExceptionInformation[1]);
    00198                         if (String.Length > 512) {
    00199                             break;
    00200                         }
    00201                         ProbeForRead(String.Buffer, String.Length, sizeof(CHAR));
    00202                         String.Buffer =
    00203                             KdpCopyDataToStack(String.Buffer, String.Length);
    00204
    00205                         ReplyString = *((PSTRING)ExceptionRecord->ExceptionInformation[2]);
    00206                         if (ReplyString.MaximumLength > 512) {
    00207                             break;
    00208                         }
    00209                         ProbeForWrite(ReplyString.Buffer,
    00210                                       ReplyString.MaximumLength,
    00211                                       sizeof(CHAR));
    00212                         Buffer = ReplyString.Buffer;
    00213                         ReplyString.Buffer =
    00214                             KdpCopyDataToStack(
    00215                                 ReplyString.Buffer,
    00216                                 ReplyString.MaximumLength
    00217                             );
    00218
    00219                     } except (EXCEPTION_EXECUTE_HANDLER) {
    00220
    00221                         //
    00222                         // If an exception occurs then don't handle
    00223                         // this DebugService request.
    00224                         //
    00225
    00226                         break;
    00227                     }
    00228                 } else {
    00229                     String = *((PSTRING)ExceptionRecord->ExceptionInformation[1]);
    00230                     ReplyString = *((PSTRING)ExceptionRecord->ExceptionInformation[2]);
    00231                 }
    00232
    00233                 //
    00234                 // Prompt, keep prompting until no breakin seen.
    00235                 //
    00236
    00237                 KdLogDbgPrint(&String);
    00238
    00239                 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    00240                 do {
    00241                     RetValue = KdpPromptString(&String, &ReplyString);
    00242                 } while (RetValue == TRUE);
    00243
    00244                 ContextRecord->Eax = ReplyString.Length;
    00245                 KdExitDebugger(Enable);
    00246
    00247                 if (PreviousMode == UserMode) {
    00248
    00249                     //
    00250                     // Restore user mode return parameters
    00251                     //
    00252
    00253                     try {
    00254                         KdpQuickMoveMemory(
    00255                             Buffer,
    00256                             ReplyString.Buffer,
    00257                             ReplyString.Length
    00258                         );
    00259                     } except (EXCEPTION_EXECUTE_HANDLER) {
    00260
    00261                         //
    00262                         // If an exception occurs then don't handle
    00263                         // this DebugService request.
    00264                         //
    00265
    00266                         break;
    00267                     }
    00268                 }
    00269
    00270                 Completion = TRUE;
    00271                 break;
    00272
    00273             //
    00274             //  ExceptionInformation[1] is file name of new module
    00275             //  ExceptionInformaiton[2] is the base of the dll
    00276             //
    00277
    00278             case BREAKPOINT_UNLOAD_SYMBOLS:
    00279                 UnloadSymbols = TRUE;
    00280
    00281                 //
    00282                 // Fall through
    00283                 //
    00284
    00285             case BREAKPOINT_LOAD_SYMBOLS:
    00286
    00287                 if (PreviousMode != KernelMode) {
    00288                     break;
    00289                 }
    00290
    00291                 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    00292
    00293                 //
    00294                 // Save and restore the processor context in case the
    00295                 // kernel debugger has been configured to stop on dll
    00296                 // loads.
    00297                 //
    00298
    00299                 Prcb = KeGetCurrentPrcb();
    00300                 KiSaveProcessorControlState(&Prcb->ProcessorState);
    00301                 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
    00302                               ContextRecord,
    00303                               sizeof(CONTEXT));
    00304
    00305                 SymbolInfo = (PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2];
    00306                 Completion =
    00307                     KdpReportLoadSymbolsStateChange((PSTRING)ExceptionRecord->ExceptionInformation[1],
    00308                                                     SymbolInfo,
    00309                                                     UnloadSymbols,
    00310                                                     &Prcb->ProcessorState.ContextFrame);
    00311
    00312                 RtlCopyMemory(ContextRecord,
    00313                               &Prcb->ProcessorState.ContextFrame,
    00314                               sizeof (CONTEXT) );
    00315
    00316                 KiRestoreProcessorControlState(&Prcb->ProcessorState);
    00317
    00318                 KdExitDebugger(Enable);
    00319                 break;
    00320
    00321             //
    00322             //  Unknown command
    00323             //
    00324
    00325             default:
    00326                 // return FALSE
    00327                 break;
    00328         }
    00329         //
    00330         // If the kernel debugger did not update the EIP, then increment
    00331         // past the breakpoint instruction.
    00332         //
    00333
    00334         if (ContextRecord->Eip == OldEip) {
    00335             ContextRecord->Eip++;
    00336         }
    00337
    00338
    00339     } else {
    00340
    00341         if  ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) ||
    00342              (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)  ||
    00343              (NtGlobalFlag & FLG_STOP_ON_EXCEPTION) ||
    00344              SecondChance) {
    00345
    00346             if (!SecondChance &&
    00347                 (ExceptionRecord->ExceptionCode == STATUS_PORT_DISCONNECTED ||
    00348                  NT_SUCCESS( ExceptionRecord->ExceptionCode )
    00349                 )
    00350                ) {
    00351                 //
    00352                 // User does not really want to see these either.
    00353                 // so do NOT report it to debugger.
    00354                 //
    00355
    00356                 return FALSE;
    00357                 }
    00358
    00359             //
    00360             // Report state change to kernel debugger on host
    00361             //
    00362
    00363
    00364             Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    00365             Prcb = KeGetCurrentPrcb();
    00366             KiSaveProcessorControlState(&Prcb->ProcessorState);
    00367             RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
    00368                           ContextRecord,
    00369                           sizeof (CONTEXT));
    00370
    00371             Completion =
    00372                 KdpReportExceptionStateChange(ExceptionRecord,
    00373                                               &Prcb->ProcessorState.ContextFrame,
    00374                                               SecondChance);
    00375
    00376             RtlCopyMemory(ContextRecord,
    00377                           &Prcb->ProcessorState.ContextFrame,
    00378                           sizeof(CONTEXT));
    00379
    00380             KiRestoreProcessorControlState(&Prcb->ProcessorState);
    00381             KdExitDebugger(Enable);
    00382
    00383             KdpControlCPressed = FALSE;
    00384
    00385         } else {
    00386
    00387             //
    00388             // This is real exception that user doesn't want to see,
    00389             // so do NOT report it to debugger.
    00390             //
    00391
    00392             // return FALSE;
    00393         }
    00394     }
    00395
    00396     _asm {
    00397         mov     esp, SavedEsp
    00398     }
    00399     return Completion;
    00400
    00401     UNREFERENCED_PARAMETER(PreviousMode);
    00402 }

VOID SaveSymLoad | ( | IN PSTRING | PathName,
|  | IN PVOID | BaseOfDll,
|  | IN LONG | ProcessId,
|  | IN BOOLEAN | UnloadSymbols
| ) |