コード例 #1
0
ファイル: kdprint.c プロジェクト: SnakeSolidNL/reactos
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)
{
    STRING PromptBuffer, ResponseBuffer;
    BOOLEAN Enable, 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 */
    Enable = 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(Enable);

    /* Return the number of characters received */
    return ResponseBuffer.Length;
}
コード例 #2
0
ファイル: kdprint.c プロジェクト: SnakeSolidNL/reactos
VOID
NTAPI
KdpSymbol(IN PSTRING DllPath,
          IN PKD_SYMBOLS_INFO SymbolInfo,
          IN BOOLEAN Unload,
          IN KPROCESSOR_MODE PreviousMode,
          IN PCONTEXT ContextRecord,
          IN PKTRAP_FRAME TrapFrame,
          IN PKEXCEPTION_FRAME ExceptionFrame)
{
    BOOLEAN Enable;
    PKPRCB Prcb = KeGetCurrentPrcb();

    /* Check if we need to do anything */
    if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;

    /* Enter the debugger */
    Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);

    /* Save the CPU Control State and save the context */
    KiSaveProcessorControlState(&Prcb->ProcessorState);
    RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
                  ContextRecord,
                  sizeof(CONTEXT));

    /* Report the new state */
    KdpReportLoadSymbolsStateChange(DllPath,
                                    SymbolInfo,
                                    Unload,
                                    &Prcb->ProcessorState.ContextFrame);

    /* Restore the processor state */
    RtlCopyMemory(ContextRecord,
                  &Prcb->ProcessorState.ContextFrame,
                  sizeof(CONTEXT));
    KiRestoreProcessorControlState(&Prcb->ProcessorState);

    /* Exit the debugger and return */
    KdExitDebugger(Enable);
}
コード例 #3
0
ファイル: kdprint.c プロジェクト: SnakeSolidNL/reactos
VOID
NTAPI
KdpCommandString(IN PSTRING NameString,
                 IN PSTRING CommandString,
                 IN KPROCESSOR_MODE PreviousMode,
                 IN PCONTEXT ContextRecord,
                 IN PKTRAP_FRAME TrapFrame,
                 IN PKEXCEPTION_FRAME ExceptionFrame)
{
    BOOLEAN Enable;
    PKPRCB Prcb = KeGetCurrentPrcb();

    /* Check if we need to do anything */
    if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;

    /* Enter the debugger */
    Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);

    /* Save the CPU Control State and save the context */
    KiSaveProcessorControlState(&Prcb->ProcessorState);
    RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
                  ContextRecord,
                  sizeof(CONTEXT));

    /* Send the command string to the debugger */
    KdpReportCommandStringStateChange(NameString,
                                      CommandString,
                                      &Prcb->ProcessorState.ContextFrame);

    /* Restore the processor state */
    RtlCopyMemory(ContextRecord,
                  &Prcb->ProcessorState.ContextFrame,
                  sizeof(CONTEXT));
    KiRestoreProcessorControlState(&Prcb->ProcessorState);

    /* Exit the debugger and return */
    KdExitDebugger(Enable);
}
コード例 #4
0
ファイル: kdtrap.c プロジェクト: conioh/os-design
BOOLEAN
KdpTrap (
    IN PKTRAP_FRAME TrapFrame,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PCONTEXT ContextRecord,
    IN KPROCESSOR_MODE PreviousMode,
    IN BOOLEAN SecondChance
    )

/*++

Routine Description:

    This routine is called whenever a exception is dispatched and the kernel
    debugger is active.

Arguments:

    TrapFrame - Supplies a pointer to a trap frame that describes the
        trap.

    ExceptionFrame - Supplies a pointer to a exception frame that describes
        the trap.

    ExceptionRecord - Supplies a pointer to an exception record that
        describes the exception.

    ContextRecord - Supplies the context at the time of the exception.

    PreviousMode - Supplies the previous processor mode.

    SecondChance - Supplies a boolean value that determines whether this is
        the second chance (TRUE) that the exception has been raised.

Return Value:

    A value of TRUE is returned if the exception is handled. Otherwise a
    value of FALSE is returned.

--*/

{

    BOOLEAN Completion;
    BOOLEAN Enable;
    BOOLEAN UnloadSymbols = FALSE;
    ULONG OldIar;
    STRING Input;
    STRING Output;
    PKPRCB Prcb;

    //
    // Synchronize processor execution, save processor state, enter debugger,
    // and flush the current TB.
    //

re_enter_debugger:
    Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    Prcb = KeGetCurrentPrcb();
    KiSaveProcessorState(TrapFrame, ExceptionFrame);
    KeFlushCurrentTb();

    //
    // If this is a breakpoint instruction, then check to determine if is
    // an internal command.
    //

    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
       ((ExceptionRecord->ExceptionInformation[0] & BREAKPOINT_CODE_MASK)
                              >= DEBUG_PRINT_BREAKPOINT)) {

        //
        // Switch on the breakpoint code.
        //

        switch (ExceptionRecord->ExceptionInformation[0] & BREAKPOINT_CODE_MASK) {

            //
            // Print a debug string.
            //
            // Arguments:
            //
            //   a0 - Supplies a pointer to an output string buffer.
            //   a1 - Supplies the length of the output string buffer.
            //

        case DEBUG_PRINT_BREAKPOINT:
            ContextRecord->Iar += 4;
            Output.Buffer = (PCHAR)ContextRecord->Gpr3;
            Output.Length = (USHORT)ContextRecord->Gpr4;
            if (KdDebuggerNotPresent == FALSE) {
                if (KdpPrintString(&Output)) {
                    ContextRecord->Gpr3 = (ULONG)STATUS_BREAKPOINT;

                } else {
                    ContextRecord->Gpr3 = (ULONG)STATUS_SUCCESS;
                }

            } else {
                ContextRecord->Gpr3 = (ULONG)STATUS_DEVICE_NOT_CONNECTED;
            }

            KiRestoreProcessorState(TrapFrame, ExceptionFrame);
            KdExitDebugger(Enable);
            return TRUE;

            //
            // Print a debug prompt string, then input a string.
            //
            //   r.3 - Supplies a pointer to an output string buffer.
            //   r.4 - Supplies the length of the output string buffer..
            //   r.5 - supplies a pointer to an input string buffer.
            //   r.6 - Supplies the length of the input string bufffer.
            //

        case DEBUG_PROMPT_BREAKPOINT:
            ContextRecord->Iar += 4;
            Output.Buffer = (PCHAR)ContextRecord->Gpr3;
            Output.Length = (USHORT)ContextRecord->Gpr4;
            Input.Buffer = (PCHAR)ContextRecord->Gpr5;
            Input.MaximumLength = (USHORT)ContextRecord->Gpr6;
            KdpPromptString(&Output, &Input);
            ContextRecord->Gpr3 = Input.Length;
            KiRestoreProcessorState(TrapFrame, ExceptionFrame);
            KdExitDebugger(Enable);
            return TRUE;

            //
            // Load the symbolic information for an image.
            //
            // Arguments:
            //
            //    r.3 - Supplies a pointer to an output string descriptor.
            //    r.4 - Supplies a the base address of the image.
            //

        case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
            UnloadSymbols = TRUE;

            //
            // Fall through
            //

        case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
            OldIar = ContextRecord->Iar;
            if (KdDebuggerNotPresent == FALSE) {
                KdpReportLoadSymbolsStateChange((PSTRING)ContextRecord->Gpr3,
                                                (PKD_SYMBOLS_INFO) ContextRecord->Gpr4,
                                                UnloadSymbols,
                                                &Prcb->ProcessorState.ContextFrame);

            }

            RtlCopyMemory(ContextRecord,
                          &Prcb->ProcessorState.ContextFrame,
                          sizeof(CONTEXT));

            KiRestoreProcessorState(TrapFrame, ExceptionFrame);
            KdExitDebugger(Enable);

            //
            // If the kernel debugger did not update the IAR, then increment
            // past the breakpoint instruction.
            //

            if (ContextRecord->Iar == OldIar) {
                ContextRecord->Iar += 4;
            }

            return TRUE;

            //
            // Unknown internal command.
            //

        default:
            break;
        }
    }

    //
    // Report state change to kernel debugger on host machine.
    //

    Completion = KdpReportExceptionStateChange(
                    ExceptionRecord,
                    &Prcb->ProcessorState.ContextFrame,
                    SecondChance);

    RtlCopyMemory(ContextRecord,
                  &Prcb->ProcessorState.ContextFrame,
                  sizeof(CONTEXT));

    KiRestoreProcessorState(TrapFrame, ExceptionFrame);
    KdExitDebugger(Enable);

    //
    // check to see if the user of the remote debugger
    // requested memory to be paged in
    //
    if (KdpPageInAddress) {

        if (KeGetCurrentIrql() <= APC_LEVEL) {

            //
            // if the IQRL is below DPC level then cause
            // the page fault to occur and then re-enter
            // the debugger.  this whole process is transparent
            // to the user.
            //
            KdpPageInData( (PUCHAR)KdpPageInAddress );
            KdpPageInAddress = 0;
            KdpControlCPending = FALSE;
            goto re_enter_debugger;

        } else {

            //
            // we cannot take a page fault
            // here so a worker item is queued to take the
            // page fault.  after the worker item takes the
            // page fault it sets the contol-c flag so that
            // the user re-enters the debugger just as if
            // control-c was pressed.
            //
            if (KdpControlCPressed) {
                ExInitializeWorkItem(
                    &KdpPageInWorkItem,
                    (PWORKER_THREAD_ROUTINE) KdpPageInData,
                    (PVOID) KdpPageInAddress
                    );
                ExQueueWorkItem( &KdpPageInWorkItem, DelayedWorkQueue );
                KdpPageInAddress = 0;
            }
        }
    }

    KdpControlCPressed = FALSE;

    return Completion;
}
コード例 #5
0
ファイル: kdprint.c プロジェクト: SnakeSolidNL/reactos
NTSTATUS
NTAPI
KdpPrint(IN ULONG ComponentId,
         IN ULONG Level,
         IN LPSTR String,
         IN USHORT Length,
         IN KPROCESSOR_MODE PreviousMode,
         IN PKTRAP_FRAME TrapFrame,
         IN PKEXCEPTION_FRAME ExceptionFrame,
         OUT PBOOLEAN Handled)
{
    NTSTATUS ReturnStatus;
    BOOLEAN Enable;
    STRING OutputString;

    /* Assume failure */
    *Handled = FALSE;

    /* Validate the mask */
    if (Level < 32) Level = 1 << Level;
    if (!(Kd_WIN2000_Mask & Level) ||
            ((ComponentId < KdComponentTableSize) &&
             !(*KdComponentTable[ComponentId] & Level)))
    {
        /* Mask validation failed */
        *Handled = TRUE;
        return STATUS_SUCCESS;
    }

    /* Normalize the length */
    Length = min(Length, 512);

    /* Check if we need to verify the buffer */
    if (PreviousMode != KernelMode)
    {
        /* FIXME: Support user-mode */
    }

    /* Setup the output string */
    OutputString.Buffer = String;
    OutputString.Length = Length;

    /* Log the print */
    //KdLogDbgPrint(&OutputString);

    /* Check for a debugger */
    if (KdDebuggerNotPresent)
    {
        /* Fail */
        *Handled = TRUE;
        return STATUS_DEVICE_NOT_CONNECTED;
    }

    /* Enter the debugger */
    Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);

    /* Print the string */
    if (KdpPrintString(&OutputString))
    {
        /* User pressed CTRL-C, breakpoint on return */
        ReturnStatus = STATUS_BREAKPOINT;
    }
    else
    {
        /* String was printed */
        ReturnStatus = STATUS_SUCCESS;
    }

    /* Exit the debugger and return */
    KdExitDebugger(Enable);
    *Handled = TRUE;
    return ReturnStatus;
}
コード例 #6
0
ファイル: kdtrap.c プロジェクト: SnakeSolidNL/reactos
BOOLEAN
NTAPI
KdpReport(IN PKTRAP_FRAME TrapFrame,
          IN PKEXCEPTION_FRAME ExceptionFrame,
          IN PEXCEPTION_RECORD ExceptionRecord,
          IN PCONTEXT ContextRecord,
          IN KPROCESSOR_MODE PreviousMode,
          IN BOOLEAN SecondChanceException)
{
    BOOLEAN Enable, Handled;
    PKPRCB Prcb;
    NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode;

    /*
     * 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))
    {
        /* 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))))
        {
            /* Let the exception handler, if any, try to handle it */
            return FALSE;
        }
    }
    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;
    }

    /* Enter the debugger */
    Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);

    /*
     * Get the KPRCB and save the CPU Control State manually instead of
     * using KiSaveProcessorState, since we already have a valid CONTEXT.
     */
    Prcb = KeGetCurrentPrcb();
    KiSaveProcessorControlState(&Prcb->ProcessorState);
    RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
                  ContextRecord,
                  sizeof(CONTEXT));

    /* Report the new state */
    Handled = KdpReportExceptionStateChange(ExceptionRecord,
                                            &Prcb->ProcessorState.
                                            ContextFrame,
                                            SecondChanceException);

    /* Now restore the processor state, manually again. */
    RtlCopyMemory(ContextRecord,
                  &Prcb->ProcessorState.ContextFrame,
                  sizeof(CONTEXT));
    KiRestoreProcessorControlState(&Prcb->ProcessorState);

    /* Exit the debugger and clear the CTRL-C state */
    KdExitDebugger(Enable);
    KdpControlCPressed = FALSE;
    return Handled;
}
コード例 #7
0
ファイル: kdtrap.c プロジェクト: conioh/os-design
BOOLEAN
KdpTrap (
    IN PKTRAP_FRAME TrapFrame,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PCONTEXT ContextRecord,
    IN KPROCESSOR_MODE PreviousMode,
    IN BOOLEAN SecondChance
    )

/*++

Routine Description:

    This routine is called whenever a exception is dispatched and the kernel
    debugger is active.

Arguments:

    TrapFrame - Supplies a pointer to a trap frame that describes the
        trap.

    ExceptionFrame - Supplies a pointer to a exception frame that describes
        the trap.

    ExceptionRecord - Supplies a pointer to an exception record that
        describes the exception.

    ContextRecord - Supplies the context at the time of the exception.

    PreviousMode - Supplies the previous processor mode.

    SecondChance - Supplies a boolean value that determines whether this is
        the second chance (TRUE) that the exception has been raised.

Return Value:

    A value of TRUE is returned if the exception is handled. Otherwise a
    value of FALSE is returned.

--*/

{

    BOOLEAN Completion;
    BOOLEAN Enable;
    BOOLEAN UnloadSymbols = FALSE;
    STRING Input;
    ULONGLONG OldFir;
    STRING Output;
    PKPRCB Prcb;

    //
    // Enter debugger and synchronize processor execution.
    //

    //
    // If this is a breakpoint instruction, then check to determine if is
    // an internal command.
    //

    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
        (ExceptionRecord->ExceptionInformation[0] >= DEBUG_PRINT_BREAKPOINT)){

        //
        // Switch on the breakpoint code.
        //

        switch (ExceptionRecord->ExceptionInformation[0]) {

            //
            // Print a debug string.
            //
            // Arguments:
            //
            //   a0 - Supplies a pointer to an output string buffer.
            //   a1 - Supplies the length of the output string buffer.
            //

        case DEBUG_PRINT_BREAKPOINT:
            ContextRecord->Fir += 4;
            Output.Buffer = (PCHAR)ContextRecord->IntA0;
            Output.Length = (USHORT)ContextRecord->IntA1;

            KdLogDbgPrint(&Output);

            if (KdDebuggerNotPresent == FALSE) {

                Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
                if (KdpPrintString(&Output)) {
                    ContextRecord->IntV0 = (ULONG)STATUS_BREAKPOINT;
                } else {
                    ContextRecord->IntV0 = (ULONG)STATUS_SUCCESS;
                }
                KdExitDebugger(Enable);

            } else {
                ContextRecord->IntV0 = (ULONG)STATUS_DEVICE_NOT_CONNECTED;
            }

            return TRUE;


            //
            // Stop in the debugger
            //
            // As this is not a normal breakpoint we must increment the
            // context past the breakpoint instruction
            //

        case BREAKIN_BREAKPOINT:
            ContextRecord->Fir += 4;
            break;

            //
            // Print a debug prompt string, then input a string.
            //
            //   a0 - Supplies a pointer to an output string buffer.
            //   a1 - Supplies the length of the output string buffer..
            //   a2 - supplies a pointer to an input string buffer.
            //   a3 - Supplies the length of the input string bufffer.
            //

        case DEBUG_PROMPT_BREAKPOINT:
            ContextRecord->Fir += 4;
            Output.Buffer = (PCHAR)ContextRecord->IntA0;
            Output.Length = (USHORT)ContextRecord->IntA1;
            Input.Buffer = (PCHAR)ContextRecord->IntA2;
            Input.MaximumLength = (USHORT)ContextRecord->IntA3;

            KdLogDbgPrint(&Output);

            Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);

            KdpPromptString(&Output, &Input);

            ContextRecord->IntV0 = Input.Length;

            KdExitDebugger(Enable);
            return TRUE;

            //
            // Load the symbolic information for an image.
            //
            // Arguments:
            //
            //    a0 - Supplies a pointer to an output string descriptor.
            //    a1 - Supplies a the base address of the image.
            //    a2 - Supplies the current process id.
            //

        case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
            UnloadSymbols = TRUE;

            //
            // Fall through
            //

        case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
            Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
            Prcb = KeGetCurrentPrcb();
            OldFir = ContextRecord->Fir;
            RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
                          ContextRecord,
                          sizeof(CONTEXT));

            if (KdDebuggerNotPresent == FALSE) {
                KdpReportLoadSymbolsStateChange((PSTRING)ContextRecord->IntA0,
                                                (PKD_SYMBOLS_INFO) ContextRecord->IntA1,
                                                UnloadSymbols,
                                                &Prcb->ProcessorState.ContextFrame);

            }

            RtlCopyMemory(ContextRecord,
                          &Prcb->ProcessorState.ContextFrame,
                          sizeof(CONTEXT));

            KdExitDebugger(Enable);

            //
            // If the kernel debugger did not update the FIR, then increment
            // past the breakpoint instruction.
            //

            if (ContextRecord->Fir == OldFir) {
                ContextRecord->Fir += 4;
            }

            return TRUE;

            //
            // Unknown internal command.
            //

        default:
            break;
        }
    }

    //
    // Report state change to kernel debugger on host machine.
    //

    Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    Prcb = KeGetCurrentPrcb();

    RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
                    ContextRecord,
                    sizeof (CONTEXT));

    Completion = KdpReportExceptionStateChange(ExceptionRecord,
                                               &Prcb->ProcessorState.ContextFrame,
                                               SecondChance);

    RtlCopyMemory(ContextRecord,
                  &Prcb->ProcessorState.ContextFrame,
                  sizeof(CONTEXT));

    KdExitDebugger(Enable);

    KdpControlCPressed = FALSE;

    //
    // Always return TRUE if this is the first chance to handle the
    // exception.  Otherwise, return the completion status of the
    // state change reporting.
    //

    if( SecondChance ){
        return Completion;
    } else {
        return TRUE;
    }
}