当前位置: 首页 > article >正文

nt!KeWaitForMultipleObjects函数分析之一个例子ExpWorkerThreadBalanceManager

第一部分:
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]


http://www.kler.cn/a/599036.html

相关文章:

  • 【玩转全栈】---- Django 基于 Websocket 实现群聊(解决channel连接不了)
  • 【QA】QT事件处理流程是怎么样的?
  • Linux内核Netfilter框架分析
  • 【CC2530 教程 二】CC2530定时器实现微秒、毫秒、秒延时函数
  • 【Vue3入门1】04-计算属性 + 侦听器
  • 01 Java微服务架构(SpringBootSpringCloudJDK)_企业级升级方案指导手册
  • 【计算机操作系统】深入剖析操作系统中的存储器管理:从基础到高级
  • LORA 中的 梯度外积是什么意思; 方差和协方差的实际含义:衡量变量的离散程度和变量间的线性相关性
  • 在linux上启动微服务
  • MySQL 的多版本并发控制
  • 【IntelliJ IDEA快速绑定Maven配置指南】
  • 奇安信2面面试题。。。
  • 基于Python的智慧金融风控系统的设计与实现
  • Spring MVC 执行流程:一个请求在 Spring MVC 中是如何执行的?
  • qt实现一个简单http服务器和客户端
  • 豪越科技消防一体化:数字中国智慧应急的关键支撑
  • Vue3自定义指令实现前端权限控制 - 按钮权限
  • 全球新闻系统发布 -- 项目启动环节
  • 固定翼无人机姿态和自稳模式
  • 区块链技术