- 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)
{
/* Call the INT2D Service */
//return STATUS_SUCCESS;
return STATUS_SUCCESS;
return DebugService(BREAKPOINT_PRINT,
DebugString->Buffer,
DebugString->Length,

View file

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

View file

@ -106,9 +106,28 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
IN BOOLEAN SecondChance)
{
KD_CONTINUE_TYPE Return;
ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
/* HACK (just like all this routine */
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) Context->Eip++;
/* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
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 */
if (KdDebuggerNotPresent) return FALSE;

View file

@ -140,7 +140,7 @@ KiRecordDr7(OUT PULONG Dr7Ptr,
NewMask |= DR_MASK(DR7_OVERRIDE_V);
/* Set DR7 override */
*DrMask = DR7_OVERRIDE_MASK;
*DrMask |= DR7_OVERRIDE_MASK;
}
else
{
@ -210,10 +210,19 @@ NTAPI
KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
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 */
if ((TrapFrame->SegCs & MODE_MASK) || (TrapFrame->EFlags & EFLAGS_V86_MASK))
if ((TrapFrame->SegCs & MODE_MASK) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Write it directly */
TrapFrame->HardwareEsp = Esp;
@ -221,7 +230,11 @@ KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
else
{
/* 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 */
if (!(TrapFrame->SegCs & FRAME_EDITED))
@ -243,6 +256,9 @@ KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
}
}
}
/* Restore IRQL */
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
}
ULONG
@ -316,12 +332,13 @@ KeContextToTrapFrame(IN PCONTEXT Context,
PFX_SAVE_AREA FxSaveArea;
ULONG i;
BOOLEAN V86Switch = FALSE;
KIRQL OldIrql = APC_LEVEL;
KIRQL OldIrql;
ULONG DrMask = 0;
PVOID SafeDr;
/* 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 */
if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
@ -544,7 +561,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
else
{
/* FIXME: Handle FPU Emulation */
ASSERT(FALSE);
//ASSERT(FALSE);
}
}
@ -600,11 +617,12 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
FLOATING_SAVE_AREA UnalignedArea;
} FloatSaveBuffer;
FLOATING_SAVE_AREA *FloatSaveArea;
KIRQL OldIrql = APC_LEVEL;
KIRQL OldIrql;
ULONG i;
/* 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 */
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
@ -817,11 +835,26 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
/* Get a Context */
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
/* Fix up EIP */
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
/* Look at our exception code */
switch (ExceptionRecord->ExceptionCode)
{
/* Decrement EIP by one */
Context.Eip--;
/* Breapoint */
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 */
@ -866,8 +899,8 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
ExceptionRecord->ExceptionCode,
(ULONG_PTR)ExceptionRecord->ExceptionAddress,
ExceptionRecord->ExceptionInformation[0],
ExceptionRecord->ExceptionInformation[1]);
(ULONG_PTR)TrapFrame,
0);
}
else
{
@ -989,8 +1022,8 @@ DispatchToUser:
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
ExceptionRecord->ExceptionCode,
(ULONG_PTR)ExceptionRecord->ExceptionAddress,
ExceptionRecord->ExceptionInformation[0],
ExceptionRecord->ExceptionInformation[1]);
(ULONG_PTR)TrapFrame,
0);
}
Handled:

View file

@ -473,43 +473,8 @@ _KiDebugService:
mov ecx, [ebp+KTRAP_FRAME_ECX]
mov edx, [ebp+KTRAP_FRAME_EDX]
/* Check for V86 mode */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
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
/* Jump to INT3 handler */
jmp PrepareInt3
.endfunc
.func NtRaiseException@12