第一部分:
1: kd> dt kTHREAD 8999c8a0
+0x02c State : 0x2 ''
+0x054 WaitBlockList : 0x8999c940 _KWAIT_BLOCK
第一个_KWAIT_BLOCK:
1: kd> dx -id 0,0,899a2278 -r1 ((CSRSRV!_KWAIT_BLOCK *)0x8999c940)
((CSRSRV!_KWAIT_BLOCK *)0x8999c940) : 0x8999c940 [Type: _KWAIT_BLOCK *]
+0x000\] WaitListEntry \[Type: _LIST_ENTRY
+0x008\] Thread : 0x8999c8a0 \[Type: _KTHREAD \*
+0x00c\]**Object : 0xf78fad78** \[Type: void \*
+0x010\] NextWaitBlock : 0x8999c958 \[Type: _KWAIT_BLOCK \*
+0x014\] WaitKey : 0x0 \[Type: unsigned short
+0x016\] WaitType : 0x1 \[Type: unsigned short
第二个_KWAIT_BLOCK:
1: kd> dx -id 0,0,899a2278 -r1 ((CSRSRV!_KWAIT_BLOCK *)0x8999c958)
((CSRSRV!_KWAIT_BLOCK *)0x8999c958) : 0x8999c958 [Type: _KWAIT_BLOCK *]
+0x000\] WaitListEntry \[Type: _LIST_ENTRY
+0x008\] Thread : 0x8999c8a0 \[Type: _KTHREAD \*
+0x00c\] Object : 0x80bf5c60 \[Type: void \*\] //80bf5c60 nt!ExpThreadSetManagerEvent = struct _KEVENT \[+0x010\] NextWaitBlock : 0x8999c970 \[Type: _KWAIT_BLOCK \*
+0x014\] WaitKey : 0x1 \[Type: unsigned short
+0x016\] WaitType : 0x1 \[Type: unsigned short
1: kd> x nt!ExpThreadSetManagerEvent
80bf5c60 nt!ExpThreadSetManagerEvent = struct _KEVENT
第三个_KWAIT_BLOCK:
1: kd> dx -id 0,0,899a2278 -r1 ((CSRSRV!_KWAIT_BLOCK *)0x8999c970)
((CSRSRV!_KWAIT_BLOCK *)0x8999c970) : 0x8999c970 [Type: _KWAIT_BLOCK *]
+0x000\] WaitListEntry \[Type: _LIST_ENTRY
+0x008\] Thread : 0x8999c8a0 \[Type: _KTHREAD \*
+0x00c\] Object : 0x80bf5c50 \[Type: void \*\] //80bf5c50 nt!ExpThreadSetManagerShutdownEvent = struct _KEVENT \[+0x010\] NextWaitBlock : 0x8999c940 \[Type: _KWAIT_BLOCK \*\] //返回到 NextWaitBlock : 0x8999c940结束 \[+0x014\] WaitKey : 0x2 \[Type: unsigned short
+0x016\] WaitType : 0x1 \[Type: unsigned short
1: kd> x nt!ExpThreadSetManagerShutdownEvent
80bf5c50 nt!ExpThreadSetManagerShutdownEvent = struct _KEVENT
第二部分:
1: kd> dt ktimer 0xf78fad78 //Object : 0xf78fad78
CSRSRV!KTIMER
+0x000 Header : _DISPATCHER_HEADER
+0x010 DueTime : _ULARGE_INTEGER 0x00002707`bbe04df6
+0x018 TimerListEntry : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x020 Dpc : (null)
+0x024 Period : 0n0
1: kd> dx -id 0,0,899a2278 -r1 (*((CSRSRV!_DISPATCHER_HEADER *)0xf78fad78))
(*((CSRSRV!_DISPATCHER_HEADER *)0xf78fad78)) [Type: _DISPATCHER_HEADER]
+0x000\] Type : 0x8 \[Type: unsigned char
+0x001\] Absolute : 0x0 \[Type: unsigned char
+0x002\] Size : 0xa \[Type: unsigned char
+0x003\] Inserted : 0x0 \[Type: unsigned char
+0x003\] DebugActive : 0x0 \[Type: unsigned char
+0x000\] Lock : 655368 \[Type: long
[+0x004] SignalState : 1 [Type: long] //定时器到期SignalState : 1
+0x008\] WaitListHead \[Type: _LIST_ENTRY
DueTime.QuadPart = - THREAD_SET_INTERVAL;
#define THREAD_SET_INTERVAL (1 * 1000 * 1000 * 10)
1: kd> dt kevent 0x80bf5c60 80bf5c60 nt!ExpThreadSetManagerEvent = struct _KEVENT
CSRSRV!KEVENT
+0x000 Header : _DISPATCHER_HEADER
1: kd> dx -id 0,0,899a2278 -r1 (*((CSRSRV!_DISPATCHER_HEADER *)0x80bf5c60))
(*((CSRSRV!_DISPATCHER_HEADER *)0x80bf5c60)) [Type: _DISPATCHER_HEADER]
+0x000\] Type : 0x1 \[Type: unsigned char
+0x001\] Absolute : 0x0 \[Type: unsigned char
+0x002\] Size : 0x4 \[Type: unsigned char
+0x003\] Inserted : 0x0 \[Type: unsigned char
+0x003\] DebugActive : 0x0 \[Type: unsigned char
+0x000\] Lock : 262145 \[Type: long
+0x004\] SignalState : 0 \[Type: long
+0x008\] WaitListHead \[Type: _LIST_ENTRY
1: kd> dt kevent 0x80bf5c50 //80bf5c50 nt!ExpThreadSetManagerShutdownEvent = struct _KEVENT
CSRSRV!KEVENT
+0x000 Header : _DISPATCHER_HEADER
1: kd> dx -id 0,0,899a2278 -r1 (*((CSRSRV!_DISPATCHER_HEADER *)0x80bf5c50))
(*((CSRSRV!_DISPATCHER_HEADER *)0x80bf5c50)) [Type: _DISPATCHER_HEADER]
+0x000\] Type : 0x1 \[Type: unsigned char
+0x001\] Absolute : 0x0 \[Type: unsigned char
+0x002\] Size : 0x4 \[Type: unsigned char
+0x003\] Inserted : 0x0 \[Type: unsigned char
+0x003\] DebugActive : 0x0 \[Type: unsigned char
+0x000\] Lock : 262145 \[Type: long
+0x004\] SignalState : 0 \[Type: long
+0x008\] WaitListHead \[Type: _LIST_ENTRY
第三部分:
VOID
ExpWorkerThreadBalanceManager (
IN PVOID StartContext
)
{
KTIMER PeriodTimer;
LARGE_INTEGER DueTime;
PVOID WaitObjects[MaximumBalanceObject];
NTSTATUS Status;
PAGED_CODE();
UNREFERENCED_PARAMETER (StartContext);
//
// Raise the thread priority to just higher than the priority of the
// critical work queue.
//
KeSetBasePriorityThread (KeGetCurrentThread(),
CRITICAL_WORK_QUEUE_PRIORITY + 1);
//
// Initialize the periodic timer and set the manager period.
//
KeInitializeTimer (&PeriodTimer);
DueTime.QuadPart = - THREAD_SET_INTERVAL;
//
// Initialize the wait object array.
//
WaitObjects[TimerExpiration] = (PVOID)&PeriodTimer;
WaitObjects[ThreadSetManagerEvent] = (PVOID)&ExpThreadSetManagerEvent;
WaitObjects[ShutdownEvent] = (PVOID)&ExpThreadSetManagerShutdownEvent;
//
// Loop forever processing events.
//
while (TRUE) {
//
// Set the timer to expire at the next periodic interval.
//
KeSetTimer (&PeriodTimer, DueTime, NULL);
//
// Wake up when the timer expires or the set manager event is
// signalled.
//
Status = KeWaitForMultipleObjects (MaximumBalanceObject,
WaitObjects,
WaitAny,
Executive,
KernelMode,
FALSE,
NULL,
NULL);
switch (Status) {
case TimerExpiration:
//
// Periodic timer expiration - go see if any work queues
// are deadlocked.
//
ExpDetectWorkerThreadDeadlock ();
break;
case ThreadSetManagerEvent:
//
// Someone has asked us to check some metrics to determine
// whether we should create another worker thread.
//
ExpCheckDynamicThreadCount ();
break;
case ShutdownEvent:
//
// Time to exit...
//
KeCancelTimer (&PeriodTimer);
ASSERT (ExpLastWorkerThread);
//
// Wait for the last worker thread to terminate
//
KeWaitForSingleObject (ExpLastWorkerThread,
Executive,
KernelMode,
FALSE,
NULL);
ObDereferenceObject (ExpLastWorkerThread);
PsTerminateSystemThread(STATUS_SYSTEM_SHUTDOWN);
break;
}
//
// Special debugger support.
//
// This checks if special debugging routines need to be run on the
// behalf of the debugger.
//
if (ExpDebuggerWork == 1) {
ExInitializeWorkItem(&ExpDebuggerWorkItem, ExpDebuggerWorker, NULL);
ExpDebuggerWork = 2;
ExQueueWorkItem(&ExpDebuggerWorkItem, DelayedWorkQueue);
}
}
}
第四部分:case TimerExpiration:分支
#define STATUS_KERNEL_APC 0x100
//
// Define balance set wait object types.
//
typedef enum _BALANCE_OBJECT {
TimerExpiration,
ThreadSetManagerEvent,
ShutdownEvent,
MaximumBalanceObject
} BALANCE_OBJECT;
switch (Status) {
case TimerExpiration:
//
// Periodic timer expiration - go see if any work queues
// are deadlocked.
//
ExpDetectWorkerThreadDeadlock ();
break;
第五部分:ExpDetectWorkerThreadDeadlock
//
// Worker Thread
//
typedef enum _WORK_QUEUE_TYPE {
CriticalWorkQueue,
DelayedWorkQueue,
HyperCriticalWorkQueue,
MaximumWorkQueue
} WORK_QUEUE_TYPE;
1: kd> x nt!ExWorkerQueue
80bf5c80 nt!ExWorkerQueue = struct _EX_WORK_QUEUE [3]
80bf5c80 nt!ExWorkerQueue = struct _EX_WORK_QUEUE []
1: kd> dx -r1 (*((ntkrnlmp!_EX_WORK_QUEUE (*)[3])0x80bf5c80))
(*((ntkrnlmp!_EX_WORK_QUEUE (*)[3])0x80bf5c80)) [Type: _EX_WORK_QUEUE [3]]
0\] \[Type: _EX_WORK_QUEUE
1\] \[Type: _EX_WORK_QUEUE
2\] \[Type: _EX_WORK_QUEUE
1: kd> dx -r1 (*((ntkrnlmp!_EX_WORK_QUEUE *)0x80bf5c80))
(*((ntkrnlmp!_EX_WORK_QUEUE *)0x80bf5c80)) [Type: _EX_WORK_QUEUE]
+0x000\] WorkerQueue \[Type: _KQUEUE
+0x028\] DynamicThreadCount : 0x0 \[Type: unsigned long
+0x02c\] WorkItemsProcessed : 0x240 \[Type: unsigned long
+0x030\] WorkItemsProcessedLastPass : 0x23f \[Type: unsigned long
+0x034\] QueueDepthLastPass : 0x0 \[Type: unsigned long
+0x038\] Info \[Type: EX_QUEUE_WORKER_INFO
1: kd> dx -r1 (*((ntkrnlmp!_EX_WORK_QUEUE *)0x80bf5cbc))
(*((ntkrnlmp!_EX_WORK_QUEUE *)0x80bf5cbc)) [Type: _EX_WORK_QUEUE]
+0x000\] WorkerQueue \[Type: _KQUEUE
+0x028\] DynamicThreadCount : 0x0 \[Type: unsigned long
+0x02c\] WorkItemsProcessed : 0x16c \[Type: unsigned long
+0x030\] WorkItemsProcessedLastPass : 0x16a \[Type: unsigned long
+0x034\] QueueDepthLastPass : 0x0 \[Type: unsigned long
+0x038\] Info \[Type: EX_QUEUE_WORKER_INFO
1: kd> dx -r1 (*((ntkrnlmp!_EX_WORK_QUEUE *)0x80bf5cf8))
(*((ntkrnlmp!_EX_WORK_QUEUE *)0x80bf5cf8)) [Type: _EX_WORK_QUEUE]
+0x000\] WorkerQueue \[Type: _KQUEUE
+0x028\] DynamicThreadCount : 0x0 \[Type: unsigned long
+0x02c\] WorkItemsProcessed : 0x7a \[Type: unsigned long
+0x030\] WorkItemsProcessedLastPass : 0x79 \[Type: unsigned long
+0x034\] QueueDepthLastPass : 0x0 \[Type: unsigned long
+0x038\] Info \[Type: EX_QUEUE_WORKER_INFO