Addendum to r68851:
- Reset the state of the worker thread *after* having captured the data, not before.
- Fix the explanations given in comments.

svn path=/trunk/; revision=68854
This commit is contained in:
Hermès Bélusca-Maïto 2015-08-29 12:53:08 +00:00
parent f0aeab590d
commit d328dc16b4
3 changed files with 23 additions and 17 deletions

View file

@ -16,7 +16,7 @@
// #ifdef _WINKD_ // #ifdef _WINKD_
/* /*
* WinDBG Debugger Worker Thread data * WinDBG Debugger Worker State Machine data
*/ */
WORK_QUEUE_ITEM ExpDebuggerWorkItem; WORK_QUEUE_ITEM ExpDebuggerWorkItem;
/* /*
@ -33,19 +33,22 @@ ULONG_PTR ExpDebuggerPageIn;
// #ifdef _WINKD_ // #ifdef _WINKD_
/* /*
* WinDBG Debugger Worker Thread * WinDBG Debugger Worker State Machine
* *
* A worker thread is queued whenever WinDBG wants to attach or kill a user-mode * This functionality is used whenever WinDBG wants to attach or kill a user-mode
* process from within live kernel-mode session, and/or page-in an address region. * process from within live kernel-mode session, and/or page-in an address region.
* It is implemented as a state machine: when it is in "Ready" state, WinDBG can
* initialize the data for the state machine, then switch its state to "Start".
* The worker thread balance manager detects this, switches the state to "Initialized"
* and queues a worker thread. As long as the state is not "Ready" again, WinDBG
* prevents from requeuing a new thread. When the thread is started, it captures
* all the data, then resets the machine state to "Ready", thus allowing WinDBG
* to requeue another worker thread.
* *
* WinDBG commands: * WinDBG commands:
* .process /i <addr> (where <addr> is the address of the EPROCESS block for this process) * .process /i <addr> (where <addr> is the address of the EPROCESS block for this process)
* .kill <addr> ( " " " " ) * .kill <addr> ( " " " " )
* .pagein <addr> (where <addr> is the address to page in) * .pagein <addr> (where <addr> is the address to page in)
*
* The implementation is very naive because the same data is reused, so that if
* the worker thread has not started before WinDBG sends fresh new data again,
* then only the latest data is taken into account.
*/ */
VOID VOID
NTAPI NTAPI
@ -59,22 +62,25 @@ ExpDebuggerWorker(IN PVOID Context)
UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(Context);
/* Be sure we were started in an initialized state */ /* Be sure we were started in an initialized state */
ASSERTMSG("ExpDebuggerWorker being entered with state != 2\n", ASSERTMSG("ExpDebuggerWorker being entered in non-initialized state!\n",
ExpDebuggerWork == WinKdWorkerInitialized); ExpDebuggerWork == WinKdWorkerInitialized);
if (ExpDebuggerWork != WinKdWorkerInitialized) return; if (ExpDebuggerWork != WinKdWorkerInitialized)
{
/* Reset the worker flag to the disabled state */ /* An error happened, so get a chance to restart proper */
ExpDebuggerWork = WinKdWorkerDisabled; ExpDebuggerWork = WinKdWorkerReady;
return;
}
/* Get the processes to be attached or killed, and the address to page in */ /* Get the processes to be attached or killed, and the address to page in */
ProcessToAttach = ExpDebuggerProcessAttach; ProcessToAttach = ExpDebuggerProcessAttach;
ProcessToKill = ExpDebuggerProcessKill; ProcessToKill = ExpDebuggerProcessKill;
PageInAddress = ExpDebuggerPageIn; PageInAddress = ExpDebuggerPageIn;
/* Reset to their default values */ /* Reset the state machine to its ready state */
ExpDebuggerProcessAttach = NULL; ExpDebuggerProcessAttach = NULL;
ExpDebuggerProcessKill = NULL; ExpDebuggerProcessKill = NULL;
ExpDebuggerPageIn = (ULONG_PTR)NULL; ExpDebuggerPageIn = (ULONG_PTR)NULL;
ExpDebuggerWork = WinKdWorkerReady;
/* Default to the current process if we don't find the process to be attached or killed */ /* Default to the current process if we don't find the process to be attached or killed */
Process = NULL; Process = NULL;

View file

@ -491,7 +491,7 @@ ExpWorkerThreadBalanceManager(IN PVOID Context)
* If WinDBG wants to attach or kill a user-mode process, and/or * If WinDBG wants to attach or kill a user-mode process, and/or
* page-in an address region, queue a debugger worker thread. * page-in an address region, queue a debugger worker thread.
*/ */
if (ExpDebuggerWork == WinKdWorkerActivate) if (ExpDebuggerWork == WinKdWorkerStart)
{ {
ExInitializeWorkItem(&ExpDebuggerWorkItem, ExpDebuggerWorker, NULL); ExInitializeWorkItem(&ExpDebuggerWorkItem, ExpDebuggerWorker, NULL);
ExpDebuggerWork = WinKdWorkerInitialized; ExpDebuggerWork = WinKdWorkerInitialized;

View file

@ -44,12 +44,12 @@ extern CHAR NtBuildLab[];
// #ifdef _WINKD_ // #ifdef _WINKD_
/* /*
* WinDBG Debugger Worker Thread data (see dbgctrl.c) * WinDBG Debugger Worker State Machine data (see dbgctrl.c)
*/ */
typedef enum _WINKD_WORKER_STATE typedef enum _WINKD_WORKER_STATE
{ {
WinKdWorkerDisabled = 0, WinKdWorkerReady = 0,
WinKdWorkerActivate, WinKdWorkerStart,
WinKdWorkerInitialized WinKdWorkerInitialized
} WINKD_WORKER_STATE; } WINKD_WORKER_STATE;