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
00095
00096
00097 mov SavedEsp, esp
00098 }
00099
00100
00101
00102
00103
00104
00105
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00106 (ExceptionRecord->ExceptionInformation[0] !=
BREAKPOINT_BREAK)) {
00107
00108
00109
00110
00111
00112
if (
KdDebuggerNotPresent &&
00113 ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_PROMPT) {
00114 ContextRecord->Eip++;
00115
return(
TRUE);
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 OldEip = ContextRecord->Eip;
00129
00130
switch (ExceptionRecord->ExceptionInformation[0]) {
00131
00132
00133
00134
00135
00136
case BREAKPOINT_PRINT:
00137
00138
if (PreviousMode ==
UserMode) {
00139
00140 EXCEPTION_RECORD exr;
00141
00142
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
00158
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
00185
00186
00187
00188
case BREAKPOINT_PROMPT:
00189
if (PreviousMode ==
UserMode) {
00190
00191
00192
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
00223
00224
00225
00226
break;
00227 }
00228 }
else {
00229
String = *((PSTRING)ExceptionRecord->ExceptionInformation[1]);
00230 ReplyString = *((PSTRING)ExceptionRecord->ExceptionInformation[2]);
00231 }
00232
00233
00234
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
00251
00252
00253
try {
00254
KdpQuickMoveMemory(
00255 Buffer,
00256 ReplyString.Buffer,
00257 ReplyString.Length
00258 );
00259 } except (EXCEPTION_EXECUTE_HANDLER) {
00260
00261
00262
00263
00264
00265
00266
break;
00267 }
00268 }
00269
00270 Completion =
TRUE;
00271
break;
00272
00273
00274
00275
00276
00277
00278
case BREAKPOINT_UNLOAD_SYMBOLS:
00279 UnloadSymbols =
TRUE;
00280
00281
00282
00283
00284
00285
case BREAKPOINT_LOAD_SYMBOLS:
00286
00287
if (PreviousMode !=
KernelMode) {
00288
break;
00289 }
00290
00291 Enable =
KdEnterDebugger(TrapFrame, ExceptionFrame);
00292
00293
00294
00295
00296
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
00323
00324
00325
default:
00326
00327
break;
00328 }
00329
00330
00331
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
00353
00354
00355
00356
return FALSE;
00357 }
00358
00359
00360
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
00389
00390
00391
00392
00393 }
00394 }
00395
00396 _asm {
00397 mov esp, SavedEsp
00398 }
00399
return Completion;
00400
00401 UNREFERENCED_PARAMETER(PreviousMode);
00402 }