- Fix critical bugs in DR_TRAP_FIXUP, TRAP_PROLOG and TRAP_EPILOG which would either cause infinite loops during exceptions or corruption of the correct code path when dealing with debug registers.

- Fix a bug in KiRecordDr7 setting the new DR7 mask.
- Make KiEspToTrapFrame thread-safe by raising to APC_LEVEL to make sure a thread/set context doesn't corrupt the state.
- Fix thread-safe IRQL Code in KeContexToTrapFrame/KeTrapFrameToContext.
- Fix KiDispatchException to properly handle KI_EXCEPTION_ACCESS_VIOLATION and convert it back to STATUS_ACCESS_VIOLATION which is what the system expects.
- Also fix the way we do bugchecks so the the trapframe gets properly put as a parameter.
- Make KiDebugService call into KiTrap3 to share code (merge from kd-branch).
- Changes to the KdpEnterDebuggerException hack we have to handle this change.
- Temporarily disable DebugPrint functionality (sorry, I'm onto a big bug here!)

svn path=/trunk/; revision=25975
This commit is contained in:
Alex Ionescu 2007-03-03 17:24:58 +00:00
parent 037363f05d
commit a195100319
5 changed files with 77 additions and 60 deletions

View file

@ -23,7 +23,7 @@ DebugPrint(IN PANSI_STRING DebugString,
IN ULONG Level) IN ULONG Level)
{ {
/* Call the INT2D Service */ /* Call the INT2D Service */
//return STATUS_SUCCESS; return STATUS_SUCCESS;
return DebugService(BREAKPOINT_PRINT, return DebugService(BREAKPOINT_PRINT,
DebugString->Buffer, DebugString->Buffer,
DebugString->Length, DebugString->Length,

View file

@ -304,7 +304,7 @@ _KiUnexpectedInterrupt&Number:
/* Set them */ /* Set them */
mov dr6, ebx mov dr6, ebx
mov dr7, ecx mov dr7, ecx
jz 3f jmp 3f
.endm .endm
// //
@ -482,12 +482,12 @@ _KiUnexpectedInterrupt&Number:
/* Flush DR7 */ /* Flush DR7 */
and dword ptr [ebp+KTRAP_FRAME_DR7], 0 and dword ptr [ebp+KTRAP_FRAME_DR7], 0
3:
/* Check if the thread was being debugged */ /* Check if the thread was being debugged */
test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF
jnz Dr_&Label jnz Dr_&Label
/* Set the Trap Frame Debug Header */ /* Set the Trap Frame Debug Header */
3:
SET_TF_DEBUG_HEADER SET_TF_DEBUG_HEADER
.endm .endm
@ -1171,7 +1171,7 @@ FastExit:
mov dr3, esi mov dr3, esi
mov dr6, edi mov dr6, edi
mov dr7, ebx mov dr7, ebx
jz 4b jmp 4b
7: 7:
/* Restore real CS value */ /* Restore real CS value */

View file

@ -106,9 +106,28 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
IN BOOLEAN SecondChance) IN BOOLEAN SecondChance)
{ {
KD_CONTINUE_TYPE Return; KD_CONTINUE_TYPE Return;
ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
/* HACK (just like all this routine */ /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) Context->Eip++; if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
(ExceptionRecord->NumberParameters > 0) &&
((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
(ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||
(ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||
(ExceptionCommand == BREAKPOINT_PRINT)))
{
/* Check if this is a debug print */
if (ExceptionCommand == BREAKPOINT_PRINT)
{
/* Print the string */
KdpServiceDispatcher(BREAKPOINT_PRINT,
(PVOID)ExceptionRecord->ExceptionInformation[1],
ExceptionRecord->ExceptionInformation[2]);
}
/* This we can handle: simply bump EIP */
Context->Eip++;
}
/* Get out of here if the Debugger isn't connected */ /* Get out of here if the Debugger isn't connected */
if (KdDebuggerNotPresent) return FALSE; if (KdDebuggerNotPresent) return FALSE;

View file

@ -140,7 +140,7 @@ KiRecordDr7(OUT PULONG Dr7Ptr,
NewMask |= DR_MASK(DR7_OVERRIDE_V); NewMask |= DR_MASK(DR7_OVERRIDE_V);
/* Set DR7 override */ /* Set DR7 override */
*DrMask = DR7_OVERRIDE_MASK; *DrMask |= DR7_OVERRIDE_MASK;
} }
else else
{ {
@ -210,10 +210,19 @@ NTAPI
KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame, KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
IN ULONG Esp) IN ULONG Esp)
{ {
ULONG Previous = KiEspFromTrapFrame(TrapFrame); KIRQL OldIrql;
ULONG Previous;
/* Raise to APC_LEVEL if needed */
OldIrql = KeGetCurrentIrql();
if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Get the old ESP */
Previous = KiEspFromTrapFrame(TrapFrame);
/* Check if this is user-mode or V86 */ /* Check if this is user-mode or V86 */
if ((TrapFrame->SegCs & MODE_MASK) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) if ((TrapFrame->SegCs & MODE_MASK) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{ {
/* Write it directly */ /* Write it directly */
TrapFrame->HardwareEsp = Esp; TrapFrame->HardwareEsp = Esp;
@ -221,7 +230,11 @@ KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
else else
{ {
/* Don't allow ESP to be lowered, this is illegal */ /* Don't allow ESP to be lowered, this is illegal */
if (Esp < Previous) KeBugCheck(SET_OF_INVALID_CONTEXT); if (Esp < Previous) KeBugCheckEx(SET_OF_INVALID_CONTEXT,
Esp,
Previous,
(ULONG_PTR)TrapFrame,
0);
/* Create an edit frame, check if it was alrady */ /* Create an edit frame, check if it was alrady */
if (!(TrapFrame->SegCs & FRAME_EDITED)) if (!(TrapFrame->SegCs & FRAME_EDITED))
@ -243,6 +256,9 @@ KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
} }
} }
} }
/* Restore IRQL */
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
} }
ULONG ULONG
@ -316,12 +332,13 @@ KeContextToTrapFrame(IN PCONTEXT Context,
PFX_SAVE_AREA FxSaveArea; PFX_SAVE_AREA FxSaveArea;
ULONG i; ULONG i;
BOOLEAN V86Switch = FALSE; BOOLEAN V86Switch = FALSE;
KIRQL OldIrql = APC_LEVEL; KIRQL OldIrql;
ULONG DrMask = 0; ULONG DrMask = 0;
PVOID SafeDr; PVOID SafeDr;
/* Do this at APC_LEVEL */ /* Do this at APC_LEVEL */
if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql); OldIrql = KeGetCurrentIrql();
if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Start with the basic Registers */ /* Start with the basic Registers */
if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
@ -544,7 +561,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
else else
{ {
/* FIXME: Handle FPU Emulation */ /* FIXME: Handle FPU Emulation */
ASSERT(FALSE); //ASSERT(FALSE);
} }
} }
@ -600,11 +617,12 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
FLOATING_SAVE_AREA UnalignedArea; FLOATING_SAVE_AREA UnalignedArea;
} FloatSaveBuffer; } FloatSaveBuffer;
FLOATING_SAVE_AREA *FloatSaveArea; FLOATING_SAVE_AREA *FloatSaveArea;
KIRQL OldIrql = APC_LEVEL; KIRQL OldIrql;
ULONG i; ULONG i;
/* Do this at APC_LEVEL */ /* Do this at APC_LEVEL */
if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql); OldIrql = KeGetCurrentIrql();
if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Start with the Control flags */ /* Start with the Control flags */
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
@ -817,11 +835,26 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
/* Get a Context */ /* Get a Context */
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context); KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
/* Fix up EIP */ /* Look at our exception code */
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) switch (ExceptionRecord->ExceptionCode)
{ {
/* Decrement EIP by one */ /* Breapoint */
Context.Eip--; case STATUS_BREAKPOINT:
/* Decrement EIP by one */
Context.Eip--;
break;
/* Internal exception */
case KI_EXCEPTION_ACCESS_VIOLATION:
/* Set correct code */
ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
if (PreviousMode == UserMode)
{
/* FIXME: Handle no execute */
}
break;
} }
/* Sanity check */ /* Sanity check */
@ -866,8 +899,8 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionCode,
(ULONG_PTR)ExceptionRecord->ExceptionAddress, (ULONG_PTR)ExceptionRecord->ExceptionAddress,
ExceptionRecord->ExceptionInformation[0], (ULONG_PTR)TrapFrame,
ExceptionRecord->ExceptionInformation[1]); 0);
} }
else else
{ {
@ -989,8 +1022,8 @@ DispatchToUser:
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionCode,
(ULONG_PTR)ExceptionRecord->ExceptionAddress, (ULONG_PTR)ExceptionRecord->ExceptionAddress,
ExceptionRecord->ExceptionInformation[0], (ULONG_PTR)TrapFrame,
ExceptionRecord->ExceptionInformation[1]); 0);
} }
Handled: Handled:

View file

@ -473,43 +473,8 @@ _KiDebugService:
mov ecx, [ebp+KTRAP_FRAME_ECX] mov ecx, [ebp+KTRAP_FRAME_ECX]
mov edx, [ebp+KTRAP_FRAME_EDX] mov edx, [ebp+KTRAP_FRAME_EDX]
/* Check for V86 mode */ /* Jump to INT3 handler */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK jmp PrepareInt3
jnz NotUserMode
/* Check if this is kernel or user-mode */
test byte ptr [ebp+KTRAP_FRAME_CS], 1
jz CallDispatch
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jnz NotUserMode
/* Re-enable interrupts */
VdmProc:
sti
/* Call the debug routine */
CallDispatch:
mov esi, ecx
mov edi, edx
mov edx, eax
mov ecx, 3
push edi
push esi
push edx
call _KdpServiceDispatcher@12
NotUserMode:
/* Get the current process */
mov ebx, [fs:KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
/* Check if this is a VDM Process */
//cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
//jz VdmProc
/* Exit through common routine */
jmp _Kei386EoiHelper@0
.endfunc .endfunc
.func NtRaiseException@12 .func NtRaiseException@12