00090 :
00091
00092 This routine
is called whenever a exception
is dispatched and
the kernel
00093 debugger
is active.
00094
00095 Arguments:
00096
00097 TrapFrame - Supplies a pointer to a trap frame that describes
the
00098 trap.
00099
00100 ExceptionFrame - Supplies a pointer to a exception frame that describes
00101
the trap.
00102
00103 ExceptionRecord - Supplies a pointer to an exception record that
00104 describes
the exception.
00105
00106 ContextRecord - Supplies
the context at
the time of
the exception.
00107
00108 PreviousMode - Supplies
the previous processor mode.
00109
00110 SecondChance - Supplies a
boolean value that determines whether
this is
00111
the second chance (TRUE) that the exception has been raised.
00112
00113 Return Value:
00114
00115 A value of TRUE is returned if the exception is handled. Otherwise a
00116 value of FALSE is returned.
00117
00118 --*/
00119
00120 {
00121
00122 BOOLEAN Completion;
00123 BOOLEAN Enable;
00124 BOOLEAN UnloadSymbols =
FALSE;
00125 STRING Input;
00126 ULONG OldFir;
00127 STRING Output;
00128 PKPRCB Prcb;
00129
00130
00131
00132
00133
00134
00135 re_enter_debugger:
00136 Enable =
KdEnterDebugger(TrapFrame, ExceptionFrame);
00137 Prcb =
KeGetCurrentPrcb();
00138
KiSaveProcessorState(TrapFrame, ExceptionFrame);
00139
KeFlushCurrentTb();
00140
00141
00142
00143
00144
00145
00146
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00147 (((ExceptionRecord->ExceptionInformation[0] &
BREAKPOINT_CODE_MASK) >>
00148
BREAKPOINT_CODE_SHIFT) >= DEBUG_PRINT_BREAKPOINT)) {
00149
00150
00151
00152
00153
00154
switch ((ExceptionRecord->ExceptionInformation[0] &
BREAKPOINT_CODE_MASK) >>
00155
BREAKPOINT_CODE_SHIFT) {
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
case DEBUG_PRINT_BREAKPOINT:
00167 Output.Buffer = (PCHAR)((ULONG)ContextRecord->XIntA0);
00168 Output.Length = (
USHORT)ContextRecord->XIntA1;
00169
if (
KdDebuggerNotPresent ==
FALSE) {
00170
if (
KdpPrintString(&Output)) {
00171 ContextRecord->XIntV0 = (ULONGLONG)((LONG)STATUS_BREAKPOINT);
00172
00173 }
else {
00174 ContextRecord->XIntV0 = (ULONGLONG)((LONG)STATUS_SUCCESS);
00175 }
00176
00177 }
else {
00178 ContextRecord->XIntV0 = (ULONGLONG)((LONG)STATUS_DEVICE_NOT_CONNECTED);
00179 }
00180
00181
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00182
KdExitDebugger(Enable);
00183 ContextRecord->Fir += 4;
00184
return TRUE;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
case DEBUG_PROMPT_BREAKPOINT:
00196 Output.Buffer = (PCHAR)((ULONG)ContextRecord->XIntA0);
00197 Output.Length = (
USHORT)ContextRecord->XIntA1;
00198 Input.Buffer = (PCHAR)((ULONG)ContextRecord->XIntA2);
00199 Input.MaximumLength = (
USHORT)ContextRecord->XIntA3;
00200
KdpPromptString(&Output, &Input);
00201 ContextRecord->XIntV0 = (LONG)Input.Length;
00202
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00203
KdExitDebugger(Enable);
00204 ContextRecord->Fir += 4;
00205
return TRUE;
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
00217 UnloadSymbols =
TRUE;
00218
00219
00220
00221
00222
00223
case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
00224 OldFir = ContextRecord->Fir;
00225
if (
KdDebuggerNotPresent ==
FALSE) {
00226
KdpReportLoadSymbolsStateChange((PSTRING)((ULONG)ContextRecord->XIntA0),
00227 (
PKD_SYMBOLS_INFO)((ULONG)ContextRecord->XIntA1),
00228 UnloadSymbols,
00229 &Prcb->ProcessorState.ContextFrame);
00230
00231 }
00232
00233 RtlCopyMemory(ContextRecord,
00234 &Prcb->ProcessorState.ContextFrame,
00235 sizeof (CONTEXT) );
00236
00237
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00238
KdExitDebugger(Enable);
00239
00240
00241
00242
00243
00244
00245
if (ContextRecord->Fir == OldFir) {
00246 ContextRecord->Fir += 4;
00247 }
00248
00249
return TRUE;
00250
00251
00252
00253
00254
00255
default:
00256
break;
00257 }
00258 }
00259
00260
00261
00262
00263
00264 Completion =
KdpReportExceptionStateChange(ExceptionRecord,
00265 &Prcb->ProcessorState.ContextFrame,
00266 SecondChance);
00267
00268 RtlCopyMemory(ContextRecord,
00269 &Prcb->ProcessorState.ContextFrame,
00270
sizeof(CONTEXT));
00271
00272
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00273
KdExitDebugger(Enable);
00274
00275
00276
00277
00278
00279
00280
if (
KdpPageInAddress) {
00281
if (KeGetCurrentIrql() <=
APC_LEVEL) {
00282
00283
00284
00285
00286
00287
00288
00289
KdpPageInData((PUCHAR)KdpPageInAddress);
00290
KdpPageInAddress = 0;
00291
KdpControlCPending =
FALSE;
00292
goto re_enter_debugger;
00293
00294 }
else {
00295
00296
00297
00298
00299
00300
00301
00302
00303
if (
KdpControlCPressed) {
00304
ExInitializeWorkItem(&KdpPageInWorkItem,
00305 (PWORKER_THREAD_ROUTINE) KdpPageInData,
00306 (PVOID) KdpPageInAddress);
00307
00308
ExQueueWorkItem( &KdpPageInWorkItem, DelayedWorkQueue );
00309
KdpPageInAddress = 0;
00310 }
00311 }
00312 }
00313
00314
KdpControlCPressed =
FALSE;
00315
return Completion;
00316 }