Author: sginsberg
Date: Sat Oct 24 00:51:39 2009
New Revision: 43705
URL:
http://svn.reactos.org/svn/reactos?rev=43705&view=rev
Log:
- Replace RtlpGetExceptionAddress by the _ReturnAddress intrinsic and add it to ARM
intrin.h as it was missing.
- Simplify RtlpCheckForActiveDebugger: Remove the BOOLEAN parameter as we would always
pass it FALSE. Always return FALSE false from kernel mode for simplicity.
- Fix a critical flaw in our exception support: RtlRaiseException and RtlRaiseStatus were
implemented in C on x86. This lead to unpredictable register corruption because the
compiler could not know that it had to preserve non-volatile registers before calling
RtlCaptureContext as the saved context is later used to restore the caller in case the
exception is handled and execution is continued. This made the functions unsafe to return
from as any non-volatile register could be corrupted. Implement them in assembly for x86
to safely capture the context using only EBP and ESP. The C versions of those routines are
still used and shared for the other architectures we support -- needs to be determined if
this is safe and correct for those architectures.
- The ntdll exception Wine exposed this issue, and all tests now pass. The remaining
failures on the build server are caused by missing or incomplete debug register support in
KVM/QEMU. Run the test in another VM or on real hardware and all the tests will pass.
- Implement Debug Prompt (DbgPrompt) support for KD and KDBG. The KDBG implementation
reads the prompt from keyboard or serial depending on the mode so that sysreg and rosdbg
can support it too.
- Properly implement RtlAssert using DbgPrompt to prompt for the action to take instead of
always doing a breakpoint. The new implementation is disabled until sysreg can support
this. Also move RtlAssert to its own file as it has nothing to do with the error routines
(nor does it belong in exception.c).
- Note that DbgPrompt was already used in PspCatchCriticalBreak, and this would have
resulted in a silent hang as BREAKPOINT_PROMPT wasn't handled at all by KDBG.
- Implement KiRaiseAssertion (10 lines of code with the trap macros) and thus support
NT_ASSERT. Add partial support for it to KDBG to print out a warning and the address of
the failure, but don't do anything else. Also add NT_ASSERT to the DDK headers so that
we can use it, but don't use it yet as the ARM method of performing this has not been
decided nor implemented.
- KiTrap3 doesn't set STATUS_SUCCESS but BREAKPOINT_BREAK. They have the same
numerical value but very different meaning -- BREAKPOINT_BREAK means that the exception is
a software breakpoint and not a debug service call. Fix some comments to document that
this is what is checked for.
- Fix inverted and broken logic in KdpReport. It would never pass second chance exceptions
to the debugger, didn't respect the stop-on-exception flag properly and would always
fail to handle some special exceptions in both first and second chance instead of just
failing to handle it in first chance. Clean up, reformat and document what is going on.
- The DebugPrint and DebugPrompt support routines only perform a 2D interrupt on x86; use
more portable comments.
- Add Alex to the programmer section of x86's kdsup.c -- he wrote KdpGetStateChange,
KdpSetContextState and the code that was previously in KdpRead/WriteControlSpace.
- Add my name to the parts of KD where I have made significant work on getting KD/WinDbg
support up and running.
- KD debugging is now quite functional and stable. Some bugs and stubs remain to be
flushed out, but overall KD is now much better and easier to use than KDBG.
Added:
trunk/reactos/lib/rtl/assert.c (with props)
Modified:
trunk/reactos/dll/ntdll/dispatch/arm/stubs_asm.s
trunk/reactos/dll/ntdll/rtl/libsupp.c
trunk/reactos/include/crt/mingw32/intrin_arm.h
trunk/reactos/include/ddk/winddk.h
trunk/reactos/include/ndk/i386/asm.h
trunk/reactos/lib/rtl/debug.c
trunk/reactos/lib/rtl/error.c
trunk/reactos/lib/rtl/exception.c
trunk/reactos/lib/rtl/i386/except.c
trunk/reactos/lib/rtl/i386/except_asm.s
trunk/reactos/lib/rtl/powerpc/except.c
trunk/reactos/lib/rtl/rtl.rbuild
trunk/reactos/lib/rtl/rtlp.h
trunk/reactos/ntoskrnl/include/internal/kd.h
trunk/reactos/ntoskrnl/include/internal/kd64.h
trunk/reactos/ntoskrnl/kd/kdmain.c
trunk/reactos/ntoskrnl/kd64/i386/kdsup.c
trunk/reactos/ntoskrnl/kd64/kdapi.c
trunk/reactos/ntoskrnl/kd64/kdbreak.c
trunk/reactos/ntoskrnl/kd64/kdinit.c
trunk/reactos/ntoskrnl/kd64/kdprint.c
trunk/reactos/ntoskrnl/kd64/kdtrap.c
trunk/reactos/ntoskrnl/kdbg/kdb_cli.c
trunk/reactos/ntoskrnl/ke/arm/stubs_asm.s
trunk/reactos/ntoskrnl/ke/i386/trap.s
trunk/reactos/ntoskrnl/rtl/libsupp.c
Modified: trunk/reactos/dll/ntdll/dispatch/arm/stubs_asm.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/dispatch/arm/stu…
==============================================================================
--- trunk/reactos/dll/ntdll/dispatch/arm/stubs_asm.s [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/dispatch/arm/stubs_asm.s [iso-8859-1] Sat Oct 24 00:51:39
2009
@@ -6,7 +6,6 @@
GENERATE_ARM_STUB LdrInitializeThunk
GENERATE_ARM_STUB RtlGetCallersAddress
GENERATE_ARM_STUB RtlUnwind
-GENERATE_ARM_STUB RtlpGetExceptionAddress
GENERATE_ARM_STUB RtlDispatchException
GENERATE_ARM_STUB RtlpGetStackLimits
GENERATE_ARM_STUB DbgUserBreakPoint
@@ -15,4 +14,3 @@
GENERATE_ARM_STUB KiIntSystemCall
GENERATE_ARM_STUB KiUserApcDispatcher
GENERATE_ARM_STUB RtlInitializeContext
-
Modified: trunk/reactos/dll/ntdll/rtl/libsupp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/rtl/libsupp.c?re…
==============================================================================
--- trunk/reactos/dll/ntdll/rtl/libsupp.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/rtl/libsupp.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -33,9 +33,10 @@
BOOLEAN
NTAPI
-RtlpCheckForActiveDebugger(BOOLEAN Type)
-{
- return (NtCurrentPeb()->BeingDebugged);
+RtlpCheckForActiveDebugger(VOID)
+{
+ /* Return the flag in the PEB */
+ return NtCurrentPeb()->BeingDebugged;
}
BOOLEAN
Modified: trunk/reactos/include/crt/mingw32/intrin_arm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/crt/mingw32/intrin…
==============================================================================
--- trunk/reactos/include/crt/mingw32/intrin_arm.h [iso-8859-1] (original)
+++ trunk/reactos/include/crt/mingw32/intrin_arm.h [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -32,6 +32,7 @@
#error Unsupported compiler
#endif
+#define _ReturnAddress() (__builtin_return_address(0))
#define _ReadWriteBarrier() __sync_synchronize()
__INTRIN_INLINE char _InterlockedCompareExchange8(volatile char * const Destination,
const char Exchange, const char Comperand)
Modified: trunk/reactos/include/ddk/winddk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=4…
==============================================================================
--- trunk/reactos/include/ddk/winddk.h [iso-8859-1] (original)
+++ trunk/reactos/include/ddk/winddk.h [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -5796,6 +5796,25 @@
#define ROUND_TO_PAGES(Size) \
((ULONG_PTR) (((ULONG_PTR) Size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
+
+
+#if defined(_X86_) || defined(_AMD64_)
+
+//
+// x86 and x64 performs a 0x2C interrupt
+//
+#define DbgRaiseAssertionFailure __int2c
+
+#elif defined(_ARM_)
+
+//
+// TODO
+//
+
+#else
+#error Unsupported Architecture
+#endif
+
#if DBG
#define ASSERT(exp) \
@@ -5807,7 +5826,7 @@
RtlAssert( #exp, __FILE__, __LINE__, msg ), FALSE : TRUE)
#define RTL_SOFT_ASSERT(exp) \
- (VOID)((!(_exp)) ? \
+ (VOID)((!(exp)) ? \
DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n", __FILE__,
__LINE__, #exp), FALSE : TRUE)
#define RTL_SOFT_ASSERTMSG(msg, exp) \
@@ -5820,6 +5839,36 @@
#define RTL_SOFT_VERIFY(exp) RTL_SOFT_ASSERT(exp)
#define RTL_SOFT_VERIFYMSG(msg, exp) RTL_SOFT_ASSERTMSG(msg, exp)
+#if defined(_MSC_VER)
+
+#define NT_ASSERT(exp) \
+ ((!(exp)) ? \
+ (__annotation(L"Debug", L"AssertFail", L#exp), \
+ DbgRaiseAssertionFailure(), FALSE) : TRUE)
+
+#define NT_ASSERTMSG(msg, exp) \
+ ((!(exp)) ? \
+ (__annotation(L"Debug", L"AssertFail", L##msg), \
+ DbgRaiseAssertionFailure(), FALSE) : TRUE)
+
+#define NT_ASSERTMSGW(msg, exp) \
+ ((!(exp)) ? \
+ (__annotation(L"Debug", L"AssertFail", msg), \
+ DbgRaiseAssertionFailure(), FALSE) : TRUE)
+
+#else
+
+//
+// GCC doesn't support __annotation (nor PDB)
+//
+#define NT_ASSERT(exp) \
+ (VOID)((!(exp)) ? (DbgRaiseAssertionFailure(), FALSE) : TRUE)
+
+#define NT_ASSERTMSG NT_ASSERT
+#define NT_ASSERTMSGW NT_ASSERT
+
+#endif
+
#else /* !DBG */
#define ASSERT(exp) ((VOID) 0)
@@ -5833,6 +5882,10 @@
#define RTL_SOFT_VERIFY(exp) ((exp) ? TRUE : FALSE)
#define RTL_SOFT_VERIFYMSG(msg, exp) ((exp) ? TRUE : FALSE)
+
+#define NT_ASSERT(exp) ((VOID)0)
+#define NT_ASSERTMSG(exp) ((VOID)0)
+#define NT_ASSERTMSGW(exp) ((VOID)0)
#endif /* DBG */
Modified: trunk/reactos/include/ndk/i386/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/i386/asm.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/i386/asm.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/i386/asm.h [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -376,6 +376,19 @@
#define CONTEXT_FLOAT_SAVE_STATUS_WORD CONTEXT_FLOAT_SAVE + FP_STATUS_WORD
#define CONTEXT_FLOAT_SAVE_TAG_WORD CONTEXT_FLOAT_SAVE + FP_TAG_WORD
#define CONTEXT_ALIGNED_SIZE 0x2CC
+#define CONTEXT_FRAME_LENGTH 0x2D0
+
+//
+// CONTEXT Flags
+//
+#ifdef __ASM__
+#define CONTEXT_CONTROL 0x10001
+#define CONTEXT_INTEGER 0x10002
+#define CONTEXT_SEGMENTS 0x10004
+#define CONTEXT_FLOATING_POINT 0x10008
+#define CONTEXT_DEBUG_REGISTERS 0x10010
+#define CONTEXT_FULL 0x10007
+#endif
//
// EXCEPTION_RECORD Offsets
@@ -527,7 +540,6 @@
// NTSTATUS, Bugcheck Codes and Debug Codes
//
#ifdef __ASM__
-#define STATUS_SUCCESS 0x00000000
#define STATUS_ACCESS_VIOLATION 0xC0000005
#define STATUS_IN_PAGE_ERROR 0xC0000006
#define STATUS_GUARD_PAGE_VIOLATION 0x80000001
@@ -553,6 +565,7 @@
#define STATUS_FLOAT_UNDERFLOW 0xC0000093
#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
+#define STATUS_ASSERTION_FAILURE 0xC0000420
#define APC_INDEX_MISMATCH 0x01
#define IRQL_NOT_GREATER_OR_EQUAL 0x09
#define IRQL_NOT_LESS_OR_EQUAL 0x0A
@@ -565,6 +578,11 @@
#define DBG_STATUS_CONTROL_C 0x01
//
+// DebugService Control Types
+//
+#define BREAKPOINT_BREAK 0x0
+
+//
// IRQL Levels
//
#define PASSIVE_LEVEL 0x0
Added: trunk/reactos/lib/rtl/assert.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/assert.c?rev=43705…
==============================================================================
--- trunk/reactos/lib/rtl/assert.c (added)
+++ trunk/reactos/lib/rtl/assert.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -1,0 +1,119 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Run-Time Library
+ * PURPOSE: Implements RtlAssert used by the ASSERT
+ * and ASSERTMSG debugging macros
+ * FILE: lib/rtl/assert.c
+ * PROGRAMERS: Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <rtl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+RtlAssert(IN PVOID FailedAssertion,
+ IN PVOID FileName,
+ IN ULONG LineNumber,
+ IN PCHAR Message OPTIONAL)
+{
+#if 0 // Disabled until sysreg can handle debug prompts
+ CHAR Action[2];
+ CONTEXT Context;
+
+ /* Capture caller's context for the debugger */
+ RtlCaptureContext(&Context);
+
+ /* Enter prompt loop */
+ for (;;)
+ {
+ /* Print the assertion */
+ DbgPrint("\n*** Assertion failed: %s%s\n"
+ "*** Source File: %s, line %ld\n\n",
+ Message != NULL ? Message : "",
+ (PSTR)FailedAssertion,
+ (PSTR)FileName,
+ LineNumber);
+
+ /* Prompt for action */
+ DbgPrompt("Break repeatedly, break Once, Ignore,"
+ " terminate Process or terminate Thread (boipt)? ",
+ Action,
+ sizeof(Action));
+ switch (Action[0])
+ {
+ /* Break repeatedly */
+ case 'B': case 'b':
+
+ /* Do a breakpoint, then prompt again */
+ DbgPrint("Execute '.cxr %p' to dump context\n",
&Context);
+ DbgBreakPoint();
+ break;
+
+ /* Ignore */
+ case 'I': case 'i':
+
+ /* Return to caller */
+ return;
+
+ /* Break once */
+ case 'O': case 'o':
+
+ /* Do a breakpoint and return */
+ DbgPrint("Execute '.cxr %p' to dump context\n",
&Context);
+ DbgBreakPoint();
+ return;
+
+ /* Terminate process*/
+ case 'P': case 'p':
+
+ /* Terminate us */
+ ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL);
+ break;
+
+ /* Terminate thread */
+ case 'T': case 't':
+
+ /* Terminate us */
+ ZwTerminateThread(ZwCurrentThread(), STATUS_UNSUCCESSFUL);
+ break;
+
+ /* Unrecognized */
+ default:
+
+ /* Prompt again */
+ break;
+ }
+ }
+
+ /* Shouldn't get here */
+ DbgBreakPoint();
+ ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL);
+#else
+ if (NULL != Message)
+ {
+ DbgPrint("Assertion \'%s\' failed at %s line %d: %s\n",
+ (PCHAR)FailedAssertion,
+ (PCHAR)FileName,
+ LineNumber,
+ Message);
+ }
+ else
+ {
+ DbgPrint("Assertion \'%s\' failed at %s line %d\n",
+ (PCHAR)FailedAssertion,
+ (PCHAR)FileName,
+ LineNumber);
+ }
+
+ DbgBreakPoint();
+#endif
+}
Propchange: trunk/reactos/lib/rtl/assert.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/lib/rtl/debug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/debug.c?rev=43705&…
==============================================================================
--- trunk/reactos/lib/rtl/debug.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/debug.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -22,7 +22,7 @@
IN ULONG ComponentId,
IN ULONG Level)
{
- /* Call the INT2D Service */
+ /* Call the Debug Service */
return DebugService(BREAKPOINT_PRINT,
DebugString->Buffer,
DebugString->Length,
@@ -35,7 +35,7 @@
DebugPrompt(IN PCSTRING Output,
IN PSTRING Input)
{
- /* Call the INT2D Service */
+ /* Call the Debug Service */
return DebugService(BREAKPOINT_PROMPT,
Output->Buffer,
Output->Length,
@@ -115,7 +115,7 @@
DebugString.Buffer = Buffer;
/* First, let the debugger know as well */
- if (RtlpCheckForActiveDebugger(FALSE))
+ if (RtlpCheckForActiveDebugger())
{
/* Fill out an exception record */
ExceptionRecord.ExceptionCode = DBG_PRINTEXCEPTION_C;
Modified: trunk/reactos/lib/rtl/error.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/error.c?rev=43705&…
==============================================================================
--- trunk/reactos/lib/rtl/error.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/error.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -810,35 +810,6 @@
/* FUNCTIONS ***************************************************************/
/*
- * @implemented
- */
-VOID
-NTAPI
-RtlAssert(PVOID FailedAssertion,
- PVOID FileName,
- ULONG LineNumber,
- PCHAR Message)
-{
- if (NULL != Message)
- {
- DbgPrint("Assertion \'%s\' failed at %s line %d: %s\n",
- (PCHAR)FailedAssertion,
- (PCHAR)FileName,
- LineNumber,
- Message);
- }
- else
- {
- DbgPrint("Assertion \'%s\' failed at %s line %d\n",
- (PCHAR)FailedAssertion,
- (PCHAR)FileName,
- LineNumber);
- }
-
- DbgBreakPoint();
-}
-
-/*
* @unimplemented
*/
NTSTATUS
Modified: trunk/reactos/lib/rtl/exception.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/exception.c?rev=43…
==============================================================================
--- trunk/reactos/lib/rtl/exception.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/exception.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -17,12 +17,14 @@
/* FUNCTIONS ***************************************************************/
+#if !defined(_M_IX86)
+
/*
* @implemented
*/
VOID
NTAPI
-RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
+RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord)
{
CONTEXT Context;
NTSTATUS Status;
@@ -30,19 +32,14 @@
/* Capture the context */
RtlCaptureContext(&Context);
-#ifdef _M_IX86
- /* Fixup ESP */
- Context.Esp += sizeof(ULONG);
-#endif
-
/* Save the exception address */
- ExceptionRecord->ExceptionAddress = RtlpGetExceptionAddress();
+ ExceptionRecord->ExceptionAddress = _ReturnAddress();
/* Write the context flag */
Context.ContextFlags = CONTEXT_FULL;
/* Check if user mode debugger is active */
- if (RtlpCheckForActiveDebugger(FALSE))
+ if (RtlpCheckForActiveDebugger())
{
/* Raise an exception immediately */
Status = ZwRaiseException(ExceptionRecord, &Context, TRUE);
@@ -68,7 +65,7 @@
#ifdef _MSC_VER
#pragma warning(push)
-#pragma warning(disable:4717)
+#pragma warning(disable:4717) // RtlRaiseStatus is recursive by design
#endif
/*
@@ -76,7 +73,7 @@
*/
VOID
NTAPI
-RtlRaiseStatus(NTSTATUS Status)
+RtlRaiseStatus(IN NTSTATUS Status)
{
EXCEPTION_RECORD ExceptionRecord;
CONTEXT Context;
@@ -84,13 +81,8 @@
/* Capture the context */
RtlCaptureContext(&Context);
-#ifdef _M_IX86
- /* Add one argument to ESP */
- Context.Esp += sizeof(PVOID);
-#endif
-
/* Create an exception record */
- ExceptionRecord.ExceptionAddress = RtlpGetExceptionAddress();
+ ExceptionRecord.ExceptionAddress = _ReturnAddress();
ExceptionRecord.ExceptionCode = Status;
ExceptionRecord.ExceptionRecord = NULL;
ExceptionRecord.NumberParameters = 0;
@@ -100,7 +92,7 @@
Context.ContextFlags = CONTEXT_FULL;
/* Check if user mode debugger is active */
- if (RtlpCheckForActiveDebugger(FALSE))
+ if (RtlpCheckForActiveDebugger())
{
/* Raise an exception immediately */
ZwRaiseException(&ExceptionRecord, &Context, TRUE);
@@ -120,6 +112,8 @@
#ifdef _MSC_VER
#pragma warning(pop)
+#endif
+
#endif
/*
Modified: trunk/reactos/lib/rtl/i386/except.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/i386/except.c?rev=…
==============================================================================
--- trunk/reactos/lib/rtl/i386/except.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/i386/except.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -235,7 +235,7 @@
ExceptionRecord3.ExceptionFlags = 0;
ExceptionRecord3.ExceptionCode = STATUS_UNWIND;
ExceptionRecord3.ExceptionRecord = NULL;
- ExceptionRecord3.ExceptionAddress = RtlpGetExceptionAddress();
+ ExceptionRecord3.ExceptionAddress = _ReturnAddress();
ExceptionRecord3.NumberParameters = 0;
}
Modified: trunk/reactos/lib/rtl/i386/except_asm.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/i386/except_asm.s?…
==============================================================================
--- trunk/reactos/lib/rtl/i386/except_asm.s [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/i386/except_asm.s [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -4,6 +4,7 @@
* FILE: lib/rtl/i386/except_asm.S
* PURPOSE: User-mode exception support for IA-32
* PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
+ * Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
@@ -39,17 +40,6 @@
/* Return */
ret 4
-.endfunc
-
-.func RtlpGetExceptionAddress@0
-.globl _RtlpGetExceptionAddress@0
-_RtlpGetExceptionAddress@0:
-
- /* Return the address from the stack */
- mov eax, [ebp+4]
-
- /* Return */
- ret
.endfunc
.func RtlCaptureContext@4
@@ -262,3 +252,150 @@
ret 16
.endfunc
+.func RtlRaiseException@4
+.globl _RtlRaiseException@4
+_RtlRaiseException@4:
+
+ /* Set up stack frame */
+ push ebp
+ mov ebp, esp
+
+ /*
+ * Save the context while preserving everything but ESP and EBP.
+ * This is vital because the caller will be restored with this context
+ * in case the execution is continued, which means we must not clobber
+ * the non-volatiles. We preserve the volatiles too because the context
+ * could get passed to a debugger.
+ */
+ lea esp, [esp-CONTEXT_FRAME_LENGTH]
+ push esp
+ call _RtlCaptureContext@4
+
+ /* Adjust ESP to account for the argument that was passed */
+ add dword ptr [esp+CONTEXT_ESP], 4
+
+ /* Save the exception address */
+ mov edx, [ebp+4]
+ mov eax, [ebp+8]
+ mov [eax+EXCEPTION_RECORD_EXCEPTION_ADDRESS], edx
+
+ /* Write the context flag */
+ mov dword ptr [esp+CONTEXT_FLAGS], CONTEXT_FULL
+
+ /* Check if user mode debugger is active */
+ call _RtlpCheckForActiveDebugger@0
+ test al, al
+ jnz DebuggerActive1
+
+ /* Dispatch the exception */
+ push esp
+ push [ebp+8]
+ call _RtlDispatchException@8
+ test al, al
+ jz RaiseException
+
+ /* Continue, go back to previous context */
+ mov ecx, esp
+ push 0
+ push ecx
+ call _ZwContinue@8
+ jmp RaiseStatus1
+
+DebuggerActive1:
+
+ /* Raise an exception immediately */
+ mov ecx, esp
+ push 1
+ push ecx
+ push [ebp+8]
+ call _ZwRaiseException@12
+ jmp RaiseStatus1
+
+RaiseException:
+
+ /* Raise the exception */
+ mov ecx, esp
+ push 0
+ push ecx
+ push [ebp+8]
+ call _ZwRaiseException@12
+
+RaiseStatus1:
+
+ /* If we returned, raise a status */
+ push eax
+ call _RtlRaiseStatus@4
+.endfunc
+
+.func RtlRaiseStatus@4
+.globl _RtlRaiseStatus@4
+_RtlRaiseStatus@4:
+
+ /* Set up stack frame */
+ push ebp
+ mov ebp, esp
+
+ /*
+ * Save the context while preserving everything but ESP and EBP.
+ * This is vital because the caller will be restored with this context
+ * in case the execution is continued, which means we must not clobber
+ * the non-volatiles. We preserve the volatiles too because the context
+ * could get passed to a debugger.
+ */
+ lea esp, [esp-CONTEXT_FRAME_LENGTH-EXCEPTION_RECORD_LENGTH]
+ push esp
+ call _RtlCaptureContext@4
+
+ /* Adjust ESP to account for the argument that was passed */
+ add dword ptr [esp+CONTEXT_ESP], 4
+
+ /* Set up the exception record */
+ lea ecx, [esp+CONTEXT_FRAME_LENGTH]
+ mov eax, [ebp+8]
+ mov dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_CODE], eax
+ mov dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
+ and dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
+ mov eax, [ebp+4]
+ mov dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_ADDRESS], eax
+ and dword ptr [ecx+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
+
+ /* Write the context flag */
+ mov dword ptr [esp+CONTEXT_FLAGS], CONTEXT_FULL
+
+ /* Check if user mode debugger is active */
+ call _RtlpCheckForActiveDebugger@0
+
+ /* Restore ECX and jump if debugger is active */
+ lea ecx, [esp+CONTEXT_FRAME_LENGTH]
+ test al, al
+ jnz DebuggerActive2
+
+ /* Dispatch the exception */
+ push esp
+ push ecx
+ call _RtlDispatchException@8
+
+ /* Raise exception if we got here */
+ lea ecx, [esp+CONTEXT_FRAME_LENGTH]
+ mov edx, esp
+ push 0
+ push edx
+ push ecx
+ call _ZwRaiseException@12
+ jmp RaiseStatus2
+
+DebuggerActive2:
+
+ /* Raise an exception immediately */
+ mov edx, esp
+ push 1
+ push edx
+ push ecx
+ call _ZwRaiseException@12
+
+RaiseStatus2:
+
+ /* If we returned, raise a status */
+ push eax
+ call _RtlRaiseStatus@4
+.endfunc
Modified: trunk/reactos/lib/rtl/powerpc/except.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/powerpc/except.c?r…
==============================================================================
--- trunk/reactos/lib/rtl/powerpc/except.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/powerpc/except.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -34,14 +34,6 @@
return TRUE;
}
-NTSYSAPI
-PVOID
-RtlpGetExceptionAddress()
-{
- // XXX arty fixme
- return NULL;
-}
-
VOID
NTAPI
RtlUnwind(IN PVOID TargetFrame OPTIONAL,
Modified: trunk/reactos/lib/rtl/rtl.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtl.rbuild?rev=437…
==============================================================================
--- trunk/reactos/lib/rtl/rtl.rbuild [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/rtl.rbuild [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -43,6 +43,7 @@
<file>access.c</file>
<file>acl.c</file>
<file>actctx.c</file>
+ <file>assert.c</file>
<file>atom.c</file>
<file>bitmap.c</file>
<file>bootdata.c</file>
Modified: trunk/reactos/lib/rtl/rtlp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtlp.h?rev=43705&a…
==============================================================================
--- trunk/reactos/lib/rtl/rtlp.h [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/rtlp.h [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -100,7 +100,7 @@
BOOLEAN
NTAPI
-RtlpCheckForActiveDebugger(BOOLEAN Type);
+RtlpCheckForActiveDebugger(VOID);
BOOLEAN
NTAPI
@@ -141,10 +141,6 @@
IN PVOID ContextData,
IN ULONG Size);
-PVOID
-NTAPI
-RtlpGetExceptionAddress(VOID);
-
VOID
NTAPI
RtlpCaptureContext(OUT PCONTEXT ContextRecord);
Modified: trunk/reactos/ntoskrnl/include/internal/kd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/kd.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/kd.h [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -207,6 +207,15 @@
KdpPrintString(
LPSTR String,
ULONG Length);
+
+ULONG
+NTAPI
+KdpPrompt(
+ IN LPSTR InString,
+ IN USHORT InStringLength,
+ OUT LPSTR OutString,
+ IN USHORT OutStringLength
+);
BOOLEAN
NTAPI
Modified: trunk/reactos/ntoskrnl/include/internal/kd64.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -201,13 +201,13 @@
OUT PBOOLEAN Status
);
-BOOLEAN
+USHORT
NTAPI
KdpPrompt(
- IN LPSTR InString,
- IN USHORT InStringLength,
- OUT LPSTR OutString,
- IN USHORT OutStringLength,
+ IN LPSTR PromptString,
+ IN USHORT PromptLength,
+ OUT LPSTR ResponseString,
+ IN USHORT MaximumResponseLength,
IN KPROCESSOR_MODE PreviousMode,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame
Modified: trunk/reactos/ntoskrnl/kd/kdmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd/kdmain.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/kd/kdmain.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd/kdmain.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -113,7 +113,8 @@
((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
(ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||
(ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||
- (ExceptionCommand == BREAKPOINT_PRINT)))
+ (ExceptionCommand == BREAKPOINT_PRINT) ||
+ (ExceptionCommand == BREAKPOINT_PROMPT)))
{
/* Check if this is a debug print */
if (ExceptionCommand == BREAKPOINT_PRINT)
@@ -126,21 +127,56 @@
/* Return success */
KeSetContextReturnRegister(Context, STATUS_SUCCESS);
}
+#ifdef KDBG
else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
{
-#ifdef KDBG
PLDR_DATA_TABLE_ENTRY LdrEntry;
/* Load symbols. Currently implemented only for KDBG! */
if(KdbpSymFindModule(((PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2])->BaseOfDll,
NULL, -1, &LdrEntry))
KdbSymProcessSymbols(LdrEntry);
+ }
+ else if (ExceptionCommand == BREAKPOINT_PROMPT)
+ {
+ ULONG ReturnValue;
+ LPSTR OutString;
+ USHORT OutStringLength;
+
+ /* Get the response string and length */
+ OutString = (LPSTR)Context->Ebx;
+ OutStringLength = (USHORT)Context->Edi;
+
+ /* Call KDBG */
+ ReturnValue = KdpPrompt((LPSTR)ExceptionRecord->
+ ExceptionInformation[1],
+ (USHORT)ExceptionRecord->
+ ExceptionInformation[2],
+ OutString,
+ OutStringLength);
+
+ /* Return the number of characters that we received */
+ Context->Eax = ReturnValue;
+ }
#endif
- }
/* This we can handle: simply bump the Program Counter */
KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
return TRUE;
}
+
+#ifdef KDBG
+ /* Check if this is an assertion failure */
+ if (ExceptionRecord->ExceptionCode == STATUS_ASSERTION_FAILURE)
+ {
+ /* Warn about it */
+ DbgPrint("\n!!! Assertion Failure at Address 0x%p !!!\n\n",
+ (PVOID)Context->Eip);
+
+ /* Bump EIP to the instruction following the int 2C and return */
+ Context->Eip += 2;
+ return TRUE;
+ }
+#endif
/* Get out of here if the Debugger isn't connected */
if (KdDebuggerNotPresent) return FALSE;
Modified: trunk/reactos/ntoskrnl/kd64/i386/kdsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/i386/kdsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/i386/kdsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/i386/kdsup.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -3,7 +3,8 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/kd64/i386/kdsup.c
* PURPOSE: KD support routines for x86
- * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
*/
/* INCLUDES *****************************************************************/
Modified: trunk/reactos/ntoskrnl/kd64/kdapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdapi.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -4,6 +4,7 @@
* FILE: ntoskrnl/kd64/kdapi.c
* PURPOSE: KD64 Public Routines and Internal Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
Modified: trunk/reactos/ntoskrnl/kd64/kdbreak.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdbreak.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdbreak.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdbreak.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -4,6 +4,7 @@
* FILE: ntoskrnl/kd64/kdbreak.c
* PURPOSE: KD64 Breakpoint Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
Modified: trunk/reactos/ntoskrnl/kd64/kdinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdinit.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdinit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdinit.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -4,6 +4,7 @@
* FILE: ntoskrnl/kd64/kdinit.c
* PURPOSE: KD64 Initialization Code
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
Modified: trunk/reactos/ntoskrnl/kd64/kdprint.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdprint.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdprint.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdprint.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -4,6 +4,7 @@
* FILE: ntoskrnl/kd64/kdprint.c
* PURPOSE: KD64 Trap Handler Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
@@ -51,6 +52,75 @@
return KdpPollBreakInWithPortLock();
}
+BOOLEAN
+NTAPI
+KdpPromptString(IN PSTRING PromptString,
+ IN PSTRING ResponseString)
+{
+ STRING Data, Header;
+ DBGKD_DEBUG_IO DebugIo;
+ ULONG Length = PromptString->Length;
+ KDSTATUS Status;
+
+ /* Copy the string to the message buffer */
+ RtlCopyMemory(KdpMessageBuffer,
+ PromptString->Buffer,
+ PromptString->Length);
+
+ /* Make sure we don't exceed the KD Packet size */
+ if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
+ {
+ /* Normalize length */
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
+ }
+
+ /* Build the packet header */
+ DebugIo.ApiNumber = DbgKdGetStringApi;
+ DebugIo.ProcessorLevel = KeProcessorLevel;
+ DebugIo.Processor = KeGetCurrentPrcb()->Number;
+ DebugIo.u.GetString.LengthOfPromptString = Length;
+ DebugIo.u.GetString.LengthOfStringRead = ResponseString->MaximumLength;
+ Header.Length = sizeof(DBGKD_DEBUG_IO);
+ Header.Buffer = (PCHAR)&DebugIo;
+
+ /* Build the data */
+ Data.Length = PromptString->Length;
+ Data.Buffer = KdpMessageBuffer;
+
+ /* Send the packet */
+ KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);
+
+ /* Set the maximum lengths for the receive */
+ Header.MaximumLength = sizeof(DBGKD_DEBUG_IO);
+ Data.MaximumLength = sizeof(KdpMessageBuffer);
+
+ /* Enter receive loop */
+ do
+ {
+ /* Get our reply */
+ Status = KdReceivePacket(PACKET_TYPE_KD_DEBUG_IO,
+ &Header,
+ &Data,
+ &Length,
+ &KdpContext);
+
+ /* Return TRUE if we need to resend */
+ if (Status == KdPacketNeedsResend) return TRUE;
+
+ /* Loop until we succeed */
+ } while (Status != KdPacketReceived);
+
+ /* Don't copy back a larger respone than there is room foor */
+ Length = min(Length, ResponseString->MaximumLength);
+
+ /* Copy back the string and return the length */
+ RtlCopyMemory(ResponseString->Buffer, KdpMessageBuffer, Length);
+ ResponseString->Length = Length;
+
+ /* Success; we don't need to resend */
+ return FALSE;
+}
+
VOID
NTAPI
KdpCommandString(IN ULONG Length,
@@ -108,20 +178,56 @@
KdExitDebugger(Entered);
}
-BOOLEAN
-NTAPI
-KdpPrompt(IN LPSTR InString,
- IN USHORT InStringLength,
- OUT LPSTR OutString,
- IN USHORT OutStringLength,
+USHORT
+NTAPI
+KdpPrompt(IN LPSTR PromptString,
+ IN USHORT PromptLength,
+ OUT LPSTR ResponseString,
+ IN USHORT MaximumResponseLength,
IN KPROCESSOR_MODE PreviousMode,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
- /* FIXME */
- KdpDprintf("KdpPrompt called\n");
- while (TRUE);
- return FALSE;
+ STRING PromptBuffer, ResponseBuffer;
+ BOOLEAN Entered, Resend;
+
+ /* Normalize the lengths */
+ PromptLength = min(PromptLength, 512);
+ MaximumResponseLength = min(MaximumResponseLength, 512);
+
+ /* Check if we need to verify the string */
+ if (PreviousMode != KernelMode)
+ {
+ /* FIXME: Handle user-mode */
+ }
+
+ /* Setup the prompt and response buffers */
+ PromptBuffer.Buffer = PromptString;
+ PromptBuffer.Length = PromptLength;
+ ResponseBuffer.Buffer = ResponseString;
+ ResponseBuffer.Length = 0;
+ ResponseBuffer.MaximumLength = MaximumResponseLength;
+
+ /* Log the print */
+ //KdLogDbgPrint(&PromptBuffer);
+
+ /* Enter the debugger */
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
+
+ /* Enter prompt loop */
+ do
+ {
+ /* Send the prompt and receive the response */
+ Resend = KdpPromptString(&PromptBuffer, &ResponseBuffer);
+
+ /* Loop while we need to resend */
+ } while (Resend);
+
+ /* Exit the debugger */
+ KdExitDebugger(Entered);
+
+ /* Return the number of characters received */
+ return ResponseBuffer.Length;
}
NTSTATUS
Modified: trunk/reactos/ntoskrnl/kd64/kdtrap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdtrap.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdtrap.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdtrap.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -4,6 +4,7 @@
* FILE: ntoskrnl/kd64/kdtrap.c
* PURPOSE: KD64 Trap Handlers
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
@@ -55,24 +56,41 @@
PKPRCB Prcb;
NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode;
- /* Check if this is single step or a breakpoint, or if we're forced to handle it
*/
+ /*
+ * Determine whether to pass the exception to the debugger.
+ * First, check if this is a "debug exception", meaning breakpoint
+ * (including debug service), single step and assertion failure exceptions.
+ */
if ((ExceptionCode == STATUS_BREAKPOINT) ||
(ExceptionCode == STATUS_SINGLE_STEP) ||
- (ExceptionCode == STATUS_ASSERTION_FAILURE) ||
- (NtGlobalFlag & FLG_STOP_ON_EXCEPTION))
- {
- /* Check if we can't really handle this */
- if ((SecondChanceException) ||
- (ExceptionCode == STATUS_PORT_DISCONNECTED) ||
- (NT_SUCCESS(ExceptionCode)))
+ (ExceptionCode == STATUS_ASSERTION_FAILURE))
+ {
+ /* This is a debug exception; we always pass them to the debugger */
+ }
+ else if (NtGlobalFlag & FLG_STOP_ON_EXCEPTION)
+ {
+ /*
+ * Not a debug exception, but the stop-on-exception flag is set,
+ * meaning the debugger requests that we pass it first chance
+ * exceptions. However, some exceptions are always passed to the
+ * exception handler first, namely exceptions with a code that isn't
+ * an error or warning code, and also exceptions with the special
+ * STATUS_PORT_DISCONNECTED code (an error code).
+ */
+ if ((SecondChanceException == FALSE) &&
+ ((ExceptionCode == STATUS_PORT_DISCONNECTED) ||
+ (NT_SUCCESS(ExceptionCode))))
{
- /* Return false to have someone else take care of the exception */
+ /* Let the exception handler, if any, try to handle it */
return FALSE;
}
}
- else if (SecondChanceException)
- {
- /* We won't bother unless this is first chance */
+ else if (SecondChanceException == FALSE)
+ {
+ /*
+ * This isn't a debug exception and the stop-on-exception flag isn't
+ * set, so don't bother
+ */
return FALSE;
}
@@ -122,7 +140,8 @@
/*
* Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or
- * Load/Unload symbols.
+ * Load/Unload symbols. Make sure it isn't a software breakpoints as those
+ * are handled by KdpReport.
*/
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
(ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))
@@ -296,7 +315,10 @@
IN PCONTEXT Context,
IN KPROCESSOR_MODE PreviousMode)
{
- /* Check if this is a breakpoint or a valid debug service */
+ /*
+ * Determine if this is a valid debug service call and make sure that
+ * it isn't a software breakpoint
+ */
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
(ExceptionRecord->NumberParameters > 0) &&
(ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))
Modified: trunk/reactos/ntoskrnl/kdbg/kdb_cli.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kdbg/kdb_cli.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kdbg/kdb_cli.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -2801,3 +2801,142 @@
ExFreePool(FileBuffer);
}
+
+VOID
+NTAPI
+KdpSerialDebugPrint(
+ LPSTR Message,
+ ULONG Length
+);
+
+STRING KdpPromptString = RTL_CONSTANT_STRING("kdb:> ");
+extern KSPIN_LOCK KdpSerialSpinLock;
+
+ULONG
+NTAPI
+KdpPrompt(IN LPSTR InString,
+ IN USHORT InStringLength,
+ OUT LPSTR OutString,
+ IN USHORT OutStringLength)
+{
+ USHORT i;
+ CHAR Response;
+ ULONG DummyScanCode;
+ KIRQL OldIrql;
+
+ /* Acquire the printing spinlock without waiting at raised IRQL */
+ while (TRUE)
+ {
+ /* Wait when the spinlock becomes available */
+ while (!KeTestSpinLock(&KdpSerialSpinLock));
+
+ /* Spinlock was free, raise IRQL */
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+ /* Try to get the spinlock */
+ if (KeTryToAcquireSpinLockAtDpcLevel(&KdpSerialSpinLock))
+ break;
+
+ /* Someone else got the spinlock, lower IRQL back */
+ KeLowerIrql(OldIrql);
+ }
+
+ /* Loop the string to send */
+ for (i = 0; i < InStringLength; i++)
+ {
+ /* Print it to serial */
+ KdPortPutByteEx(&SerialPortInfo, *(PCHAR)(InString + i));
+ }
+
+ /* Print a new line for log neatness */
+ KdPortPutByteEx(&SerialPortInfo, '\r');
+ KdPortPutByteEx(&SerialPortInfo, '\n');
+
+ /* Print the kdb prompt */
+ for (i = 0; i < KdpPromptString.Length; i++)
+ {
+ /* Print it to serial */
+ KdPortPutByteEx(&SerialPortInfo,
+ *(KdpPromptString.Buffer + i));
+ }
+
+ /* Loop the whole string */
+ for (i = 0; i < OutStringLength; i++)
+ {
+ /* Check if this is serial debugging mode */
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ {
+ /* Get the character from serial */
+ do
+ {
+ Response = KdbpTryGetCharSerial(MAXULONG);
+ } while (Response == -1);
+ }
+ else
+ {
+ /* Get the response from the keyboard */
+ do
+ {
+ Response = KdbpTryGetCharKeyboard(&DummyScanCode, MAXULONG);
+ } while (Response == -1);
+ }
+
+ /* Check for return */
+ if (Response == '\r')
+ {
+ /*
+ * We might need to discard the next '\n'.
+ * Wait a bit to make sure we receive it.
+ */
+ KeStallExecutionProcessor(100000);
+
+ /* Check the mode */
+ if (KdbDebugState & KD_DEBUG_KDSERIAL)
+ {
+ /* Read and discard the next character, if any */
+ KdbpTryGetCharSerial(5);
+ }
+ else
+ {
+ /* Read and discard the next character, if any */
+ KdbpTryGetCharKeyboard(&DummyScanCode, 5);
+ }
+
+ /*
+ * Null terminate the output string -- documentation states that
+ * DbgPrompt does not null terminate, but it does
+ */
+ *(PCHAR)(OutString + i) = 0;
+
+ /* Print a new line */
+ KdPortPutByteEx(&SerialPortInfo, '\r');
+ KdPortPutByteEx(&SerialPortInfo, '\n');
+
+ /* Release spinlock */
+ KiReleaseSpinLock(&KdpSerialSpinLock);
+
+ /* Lower IRQL back */
+ KeLowerIrql(OldIrql);
+
+ /* Return the length */
+ return OutStringLength + 1;
+ }
+
+ /* Write it back and print it to the log */
+ *(PCHAR)(OutString + i) = Response;
+ KdPortPutByteEx(&SerialPortInfo, Response);
+ }
+
+ /* Print a new line */
+ KdPortPutByteEx(&SerialPortInfo, '\r');
+ KdPortPutByteEx(&SerialPortInfo, '\n');
+
+ /* Release spinlock */
+ KiReleaseSpinLock(&KdpSerialSpinLock);
+
+ /* Lower IRQL back */
+ KeLowerIrql(OldIrql);
+
+ /* Return the length */
+ return OutStringLength;
+}
Modified: trunk/reactos/ntoskrnl/ke/arm/stubs_asm.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/stubs_asm.…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/stubs_asm.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/stubs_asm.s [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -10,7 +10,6 @@
GENERATE_ARM_STUB _local_unwind2
GENERATE_ARM_STUB RtlGetCallersAddress
GENERATE_ARM_STUB RtlUnwind
-GENERATE_ARM_STUB RtlpGetExceptionAddress
GENERATE_ARM_STUB RtlDispatchException
GENERATE_ARM_STUB RtlpGetStackLimits
GENERATE_ARM_STUB DbgBreakPointWithStatus
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -132,7 +132,6 @@
_KiGetTickCount:
_KiCallbackReturn:
-_KiRaiseAssertion:
/* FIXME: TODO */
UNHANDLED_PATH
@@ -461,6 +460,29 @@
/* FIXME: TODO */
UNHANDLED_PATH
+.func KiRaiseAssertion
+TRAP_FIXUPS kira_a, kira_t, DoFixupV86, DoFixupAbios
+_KiRaiseAssertion:
+
+ /* Push error code */
+ push 0
+
+ /* Enter trap */
+ TRAP_PROLOG kira_a, kira_t
+
+ /*
+ * Modify EIP so it points to the faulting instruction and set it as the
+ * exception address. Note that the 'int 2C' instruction used for this call
+ * is 2 bytes long as opposed to 1 byte 'int 3'.
+ */
+ sub dword ptr [ebp+KTRAP_FRAME_EIP], 2
+ mov ebx, [ebp+KTRAP_FRAME_EIP]
+
+ /* Raise an assertion failure */
+ mov eax, STATUS_ASSERTION_FAILURE
+ jmp _DispatchNoParam
+.endfunc
+
.func KiDebugService
TRAP_FIXUPS kids_a, kids_t, DoFixupV86, DoFixupAbios
_KiDebugService:
@@ -780,8 +802,11 @@
/* Enter trap */
TRAP_PROLOG kit3_a, kit3_t
- /* Set status code */
- mov eax, STATUS_SUCCESS
+ /*
+ * Set the special code to indicate that this is a software breakpoint
+ * and not a debug service call
+ */
+ mov eax, BREAKPOINT_BREAK
/* Check for V86 */
PrepareInt3:
Modified: trunk/reactos/ntoskrnl/rtl/libsupp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/rtl/libsupp.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/rtl/libsupp.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/rtl/libsupp.c [iso-8859-1] Sat Oct 24 00:51:39 2009
@@ -44,10 +44,10 @@
BOOLEAN
NTAPI
-RtlpCheckForActiveDebugger(BOOLEAN Type)
+RtlpCheckForActiveDebugger(VOID)
{
/* This check is meaningless in kernel-mode */
- return Type;
+ return FALSE;
}
BOOLEAN