Esempio n. 1
0
VOID
KdpSetStateChange (
    IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange,
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PCONTEXT ContextRecord,
    IN BOOLEAN SecondChance
    )

/*++

Routine Description:

    Fill in the Wait_State_Change message record.

Arguments:

    WaitStateChange - Supplies pointer to record to fill in

    ExceptionRecord - Supplies a pointer to an exception record.

    ContextRecord - Supplies a pointer to a context record.

    SecondChance - Supplies a boolean value that determines whether this is
        the first or second chance for the exception.

Return Value:

    None.

--*/

{

    BOOLEAN status;

    //
    //  Set up description of event, including exception record
    //

    WaitStateChange->NewState = DbgKdExceptionStateChange;
    WaitStateChange->ProcessorLevel = KeProcessorLevel;
    WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;
    WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;
    WaitStateChange->Thread = (PVOID)KeGetCurrentThread();
    WaitStateChange->ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
    KdpQuickMoveMemory(
                (PCHAR)&WaitStateChange->u.Exception.ExceptionRecord,
                (PCHAR)ExceptionRecord,
                sizeof(EXCEPTION_RECORD)
                );
    WaitStateChange->u.Exception.FirstChance = !SecondChance;

    //
    //  Copy instruction stream immediately following location of event
    //

    WaitStateChange->ControlReport.InstructionCount =
        KdpMoveMemory(
            &(WaitStateChange->ControlReport.InstructionStream[0]),
            WaitStateChange->ProgramCounter,
            DBGKD_MAXSTREAM
            );

    //
    //  Copy context record immediately following instruction stream
    //

    if (KdpSendContext) {
        KdpMoveMemory((PCHAR)&WaitStateChange->Context,
                      (PCHAR)ContextRecord,
                      sizeof(*ContextRecord));
    }

    //
    //  Clear breakpoints in copied area
    //

    status = KdpDeleteBreakpointRange(
        WaitStateChange->ProgramCounter,
        (PVOID)((PUCHAR)WaitStateChange->ProgramCounter +
            WaitStateChange->ControlReport.InstructionCount - 1)
        );

    //
    //  If there were any breakpoints cleared, recopy the area without them
    //

    if (status == TRUE) {
        KdpMoveMemory(
            &(WaitStateChange->ControlReport.InstructionStream[0]),
            WaitStateChange->ProgramCounter,
            WaitStateChange->ControlReport.InstructionCount
            );
    }
}
Esempio n. 2
0
VOID
KdpSetStateChange (
    IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange,
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PCONTEXT ContextRecord,
    IN BOOLEAN SecondChance
    )

/*++

Routine Description:

    Fill in the Wait_State_Change message record.

Arguments:

    WaitStateChange - Supplies pointer to record to fill in

    ExceptionRecord - Supplies a pointer to an exception record.

    ContextRecord - Supplies a pointer to a context record.

    SecondChance - Supplies a boolean value that determines whether this is
        the first or second chance for the exception.

Return Value:

    None.

--*/

{

    ULONG Count;
    PVOID End;

    //
    // Set up description of event, including exception record
    //

    WaitStateChange->NewState = DbgKdExceptionStateChange;
    WaitStateChange->ProcessorLevel = KeProcessorLevel;
    WaitStateChange->Processor = (USHORT)KdpGetCurrentPrcb()->Number;
    WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;
    WaitStateChange->Thread = (ULONG_PTR)KdpGetCurrentThread();
    WaitStateChange->ProgramCounter = (ULONG_PTR)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
    if (sizeof(EXCEPTION_RECORD) == sizeof(WaitStateChange->u.Exception.ExceptionRecord)) {
        KdpQuickMoveMemory((PCHAR)&WaitStateChange->u.Exception.ExceptionRecord,
                           (PCHAR)ExceptionRecord,
                           sizeof(EXCEPTION_RECORD));
    } else {
        ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord,
                              &WaitStateChange->u.Exception.ExceptionRecord
                              );
    }

    WaitStateChange->u.Exception.FirstChance = !SecondChance;

    //
    // Copy the immediate instruction stream into the control report structure.
    //

    Count =  KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0],
                           (PVOID)WaitStateChange->ProgramCounter,
                           DBGKD_MAXSTREAM);

    WaitStateChange->ControlReport.InstructionCount = (USHORT)Count;

    //
    // Clear breakpoints in the copied instruction stream. If any breakpoints
    // are clear, then recopy the instruction strasm.
    //

    End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1);
    if (KdpDeleteBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End) != FALSE) {
        KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0],
                      (PVOID)WaitStateChange->ProgramCounter,
                      Count);
    }

    //
    // Copy the context record into the wait state structure.
    //

    KdpMoveMemory((PCHAR)&WaitStateChange->Context,
                  (PCHAR)ContextRecord,
                  sizeof(*ContextRecord));

    return;
}
Esempio n. 3
0
VOID
KiFreezeTargetExecution (
    IN PKTRAP_FRAME TrapFrame,
    IN PKEXCEPTION_FRAME ExceptionFrame
    )

/*++

Routine Description:

    This function freezes the execution of the current running processor.
    If a trapframe is supplied to current state is saved into the prcb
    for the debugger.

Arguments:

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

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

Return Value:

    None.

--*/

{

#if !defined(NT_UP)

    KIRQL OldIrql;
    PKPRCB Prcb;
    BOOLEAN Enable;
    KCONTINUE_STATUS Status;
    EXCEPTION_RECORD ExceptionRecord;

    Enable = KiDisableInterrupts();
    KeRaiseIrql(HIGH_LEVEL, &OldIrql);

    Prcb = KeGetCurrentPrcb();
    Prcb->IpiFrozen = TARGET_FROZEN;
    Prcb->SkipTick  = TRUE;

    if (TrapFrame != NULL) {
        KiSaveProcessorState(TrapFrame, ExceptionFrame);
    }

    //
    // Sweep the data cache in case this is a system crash and the bug
    // check code is attempting to write a crash dump file.
    //

    KeSweepCurrentDcache();

    //
    //  Wait for person requesting us to freeze to
    //  clear our frozen flag
    //

    while (FrozenState(Prcb->IpiFrozen) == TARGET_FROZEN) {
        if (Prcb->IpiFrozen & FREEZE_ACTIVE) {

            //
            // This processor has been made the active processor
            //
            if (TrapFrame) {
                RtlZeroMemory (&ExceptionRecord, sizeof ExceptionRecord);
                ExceptionRecord.ExceptionCode = STATUS_WAKE_SYSTEM_DEBUGGER;
                ExceptionRecord.ExceptionRecord  = &ExceptionRecord;
                ExceptionRecord.ExceptionAddress =
                    (PVOID)CONTEXT_TO_PROGRAM_COUNTER (&Prcb->ProcessorState.ContextFrame);

                Status = (KiDebugSwitchRoutine) (
                            &ExceptionRecord,
                            &Prcb->ProcessorState.ContextFrame,
                            FALSE
                            );

            } else {
                Status = ContinueError;
            }

            //
            // If status is anything other then, continue with next
            // processor then reselect master
            //

            if (Status != ContinueNextProcessor) {
                Prcb->IpiFrozen &= ~FREEZE_ACTIVE;
                KiFreezeOwner->IpiFrozen |= FREEZE_ACTIVE;
            }
        }
        KeYieldProcessor();
    }

    if (TrapFrame != NULL) {
        KiRestoreProcessorState(TrapFrame, ExceptionFrame);
    }

    Prcb->IpiFrozen = RUNNING;

    KeFlushCurrentTb();
    KeSweepCurrentIcache();

    KeLowerIrql(OldIrql);
    KiRestoreInterrupts(Enable);
#endif      // !define(NT_UP)

    return;
}
Esempio n. 4
0
VOID
SetThreadFields(
    PSYSTEM_THREAD_INFORMATION ThreadInfo,
    HWND hwnd
    )
{
    TIME_FIELDS UserTime;
    TIME_FIELDS KernelTime;
    TIME_FIELDS RunTime;
    LARGE_INTEGER Time;
    CHAR TimeString[15];
    CHAR StartString[32];
    HANDLE hThread;
    CONTEXT ThreadContext;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES Obja;
    ULONG PcValue;

    //
    // Display the selected thread information
    //

    //
    // Compute runtimes
    //

    RtlTimeToTimeFields ( &ThreadInfo->UserTime, &UserTime);
    RtlTimeToTimeFields ( &ThreadInfo->KernelTime, &KernelTime);

    RtlTimeToTimeFields ( &ThreadInfo->UserTime, &UserTime);
    RtlTimeToTimeFields ( &ThreadInfo->KernelTime, &KernelTime);
    Time.QuadPart = RefreshTimeOfDayInfo.CurrentTime.QuadPart - ThreadInfo->CreateTime.QuadPart;
    RtlTimeToTimeFields ( &Time, &RunTime);
    wsprintf(TimeString,"%3ld:%02ld:%02ld.%03ld",
                RunTime.Hour,
                RunTime.Minute,
                RunTime.Second,
                RunTime.Milliseconds
                );
    SetDlgItemText(
        hwnd,
        PXPLODE_THREADELAPSED_TIME,
        TimeString
        );

    wsprintf(TimeString,"%3ld:%02ld:%02ld.%03ld",
                UserTime.Hour,
                UserTime.Minute,
                UserTime.Second,
                UserTime.Milliseconds
                );
    SetDlgItemText(
        hwnd,
        PXPLODE_THREADUSER_TIME,
        TimeString
        );

    wsprintf(TimeString,"%3ld:%02ld:%02ld.%03ld",
                KernelTime.Hour,
                KernelTime.Minute,
                KernelTime.Second,
                KernelTime.Milliseconds
                );
    SetDlgItemText(
        hwnd,
        PXPLODE_THREADKERNEL_TIME,
        TimeString
        );

    wsprintf(StartString,"0x%08lx",
                ThreadInfo->StartAddress
                );
    SetDlgItemText(
        hwnd,
        PXPLODE_THREAD_START,
        StartString
        );

    //
    // Do the priority Group
    //

    SetDlgItemInt(
        hwnd,
        PXPLODE_THREAD_DYNAMIC,
        ThreadInfo->Priority,
        FALSE
        );
    switch ( ThreadInfo->BasePriority - DlgProcessInfo->BasePriority ) {

        case 2:
            CheckRadioButton(
                hwnd,
                PXPLODE_THREAD_HIGHEST,
                PXPLODE_THREAD_LOWEST,
                PXPLODE_THREAD_HIGHEST
                );
            break;

        case 1:
            CheckRadioButton(
                hwnd,
                PXPLODE_THREAD_HIGHEST,
                PXPLODE_THREAD_LOWEST,
                PXPLODE_THREAD_ABOVE
                );
            break;

        case -1:
            CheckRadioButton(
                hwnd,
                PXPLODE_THREAD_HIGHEST,
                PXPLODE_THREAD_LOWEST,
                PXPLODE_THREAD_BELOW
                );
            break;
        case -2:
            CheckRadioButton(
                hwnd,
                PXPLODE_THREAD_HIGHEST,
                PXPLODE_THREAD_LOWEST,
                PXPLODE_THREAD_LOWEST
                );
            break;
        case 0:
        default:
            CheckRadioButton(
                hwnd,
                PXPLODE_THREAD_HIGHEST,
                PXPLODE_THREAD_LOWEST,
                PXPLODE_THREAD_NORMAL
                );
            break;
        }
    //
    // Complete thread information
    //

    SetDlgItemInt(
        hwnd,
        PXPLODE_THREAD_SWITCHES,
        ThreadInfo->ContextSwitches,
        FALSE
        );

    PcValue = 0;
    InitializeObjectAttributes(&Obja, NULL, 0, NULL, NULL);
    Status = NtOpenThread(
                &hThread,
                THREAD_GET_CONTEXT,
                &Obja,
                &ThreadInfo->ClientId
                );
    if ( NT_SUCCESS(Status) ) {
        ThreadContext.ContextFlags = CONTEXT_CONTROL;
        Status = NtGetContextThread(hThread,&ThreadContext);
        NtClose(hThread);
        if ( NT_SUCCESS(Status) ) {
            PcValue = (ULONG) CONTEXT_TO_PROGRAM_COUNTER(&ThreadContext);
            }
        }
    if ( PcValue ) {
        wsprintf(StartString,"0x%08lx",
                    PcValue
                    );
        SetDlgItemText(
            hwnd,
            PXPLODE_THREAD_PC,
            StartString
            );
        }
    else {
        SetDlgItemText(
            hwnd,
            PXPLODE_THREAD_PC,
            "Unknown"
            );
        }


    //
    // Disable the thread buttons if we can't get at the thread or it's token
    //

    {
        HANDLE Thread;
        HANDLE Token;
        BOOL ThreadOK = FALSE;
        BOOL GotToken = FALSE;

        Thread = OpenThread(MAXIMUM_ALLOWED, FALSE, (DWORD)ThreadInfo->ClientId.UniqueThread);
        if (Thread != NULL) {

            ThreadOK = TRUE;

            if (OpenThreadToken(Thread, MAXIMUM_ALLOWED, TRUE, &Token)) {
                GotToken = TRUE;
                CloseHandle(Token);
            }
            CloseHandle(Thread);
        }

        EnableWindow(GetDlgItem(hwnd, PXPLODE_THREAD_ACL), ThreadOK);

        EnableWindow(GetDlgItem(hwnd, PXPLODE_THREAD_TOKEN), GotToken);
        EnableWindow(GetDlgItem(hwnd, PXPLODE_THREAD_TOKEN_ACL), GotToken);
    }
}