Author: tkreuzer Date: Thu Apr 29 18:39:52 2010 New Revision: 47060
URL: http://svn.reactos.org/svn/reactos?rev=47060&view=rev Log: [NTOSKRNL] - On backtraces, print the address of the call instruction (assumed 5 bytes lentgh) instead of the return address, which in many cases does not make sense. (WinDbg does it this way, too) - Fix Ke386SaveFpuState to store the fpu state in the buffer, but in the pointer to the buffer - Anable Ke386SaveFpuState to save the floating point state in KiNpxHandler and KiTrap13Handler, so we know what error we got. - Disable saving debug registers in the trap frame, as long as the kernel doesn't support this - Fixes ntdll_winetest exception / OllyDbg freeze/reboot
See issue #5301 for more details.
Modified: trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h trunk/reactos/ntoskrnl/kdbg/kdb_cli.c trunk/reactos/ntoskrnl/ke/i386/exp.c trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
Modified: trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h [iso-8859-1] Thu Apr 29 18:39:52 2010 @@ -42,11 +42,11 @@ extern ULONG KeI386FxsrPresent; if (KeI386FxsrPresent) { - __asm__ __volatile__ ("fxsave %0\n" : : "m"(SaveArea)); + __asm__ __volatile__ ("fxsave %0\n" : : "m"(*SaveArea)); } else { - __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(SaveArea)); + __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(*SaveArea)); } }
Modified: trunk/reactos/ntoskrnl/kdbg/kdb_cli.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kdbg/kdb_cli.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] Thu Apr 29 18:39:52 2010 @@ -823,7 +823,8 @@ break; }
- if (!KdbSymPrintAddress((PVOID)Address)) + /* Print the location of the call instruction */ + if (!KdbSymPrintAddress((PVOID)(Address - 5))) KdbpPrint("<%08x>\n", Address); else KdbpPrint("\n");
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/exp.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] Thu Apr 29 18:39:52 2010 @@ -584,7 +584,7 @@ }
/* Handle the Debug Registers */ - if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS) + if (0 && (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS) { /* Loop DR registers */ for (i = 0; i < 4; i++)
Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Thu Apr 29 18:39:52 2010 @@ -240,7 +240,7 @@ }
/* User or kernel trap -- get ready to issue an exception */ - if (Thread->NpxState == NPX_STATE_NOT_LOADED) + //if (Thread->NpxState == NPX_STATE_NOT_LOADED) { /* Update CR0 */ Cr0 = __readcr0(); @@ -248,7 +248,7 @@ __writecr0(Cr0);
/* Save FPU state */ - //Ke386SaveFpuState(SaveArea); + Ke386SaveFpuState(SaveArea);
/* Mark CR0 state dirty */ Cr0 |= NPX_STATE_NOT_LOADED; @@ -1082,64 +1082,64 @@ * we should probably table this for now since it's not a "real" issue. */
- /* - * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call) - * which will cause a GPF since the trap frame is a total mess (on purpose) - * as built in KiEnterV86Mode. - * - * The idea is to scan for IRET, scan for the known EIP adress, validate CS - * and then manually issue a jump to the V8086 return EIP. - */ - Instructions = (PUCHAR)TrapFrame->Eip; - if (Instructions[0] == 0xCF) - { - /* - * Some evil shit is going on here -- this is not the SS:ESP you're - * looking for! Instead, this is actually CS:EIP you're looking at! - * Why? Because part of the trap frame actually corresponds to the IRET - * stack during the trap exit! - */ - if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) && - (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK))) - { - /* Exit the V86 trap! */ - Ki386BiosCallReturnAddress(TrapFrame); - } - else - { - /* Otherwise, this is another kind of IRET fault */ - UNIMPLEMENTED; - while (TRUE); - } - } + /* + * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call) + * which will cause a GPF since the trap frame is a total mess (on purpose) + * as built in KiEnterV86Mode. + * + * The idea is to scan for IRET, scan for the known EIP adress, validate CS + * and then manually issue a jump to the V8086 return EIP. + */ + Instructions = (PUCHAR)TrapFrame->Eip; + if (Instructions[0] == 0xCF) + { + /* + * Some evil shit is going on here -- this is not the SS:ESP you're + * looking for! Instead, this is actually CS:EIP you're looking at! + * Why? Because part of the trap frame actually corresponds to the IRET + * stack during the trap exit! + */ + if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) && + (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK))) + { + /* Exit the V86 trap! */ + Ki386BiosCallReturnAddress(TrapFrame); + } + else + { + /* Otherwise, this is another kind of IRET fault */ + UNIMPLEMENTED; + while (TRUE); + } + }
/* So since we're not dealing with the above case, check for RDMSR/WRMSR */ - if ((Instructions[0] == 0xF) && // 2-byte opcode + if ((Instructions[0] == 0xF) && // 2-byte opcode (((Instructions[1] >> 8) == 0x30) || // RDMSR ((Instructions[2] >> 8) == 0x32))) // WRMSR - { + { /* Unknown CPU MSR, so raise an access violation */ KiDispatchException0Args(STATUS_ACCESS_VIOLATION, TrapFrame->Eip, TrapFrame); - } - - /* Check for lazy segment load */ - if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK)) - { - /* Fix it */ - TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK); - } - else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK)) - { + } + + /* Check for lazy segment load */ + if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK)) + { + /* Fix it */ + TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK); + } + else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK)) + { /* Fix it */ TrapFrame->SegEs = (KGDT_R3_DATA | RPL_MASK); - } - else - { - /* Whatever it is, we can't handle it */ - KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame); - } + } + else + { + /* Whatever it is, we can't handle it */ + KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame); + }
/* Return to where we came from */ KiTrapReturn(TrapFrame); @@ -1353,7 +1353,7 @@ __writecr0(Cr0);
/* Save FPU state */ - //Ke386SaveFpuState(SaveArea); + Ke386SaveFpuState(SaveArea);
/* Mark CR0 state dirty */ Cr0 |= NPX_STATE_NOT_LOADED; @@ -1379,7 +1379,7 @@ FSW_UNDERFLOW | FSW_PRECISION); Error &= MxCsrMask; - + /* Now handle any of those legal errors */ if (Error & (FSW_INVALID_OPERATION | FSW_DENORMAL |