• 非分页池的消耗


    我最近在处理一个问题,服务器在几天内耗尽了NonPagedPool。通常,我们只需要使用像PoolMon这样的工具来识别有问题的pool标记,然后使用本文中的方法找到使用该pool标记的驱动程序。然而,让这个案例有趣的是pool标记,而且我们无法使用常规方法识别驱动程序。你一会儿就会明白我的意思了。支持给我提供了服务器处于状态时的内核转储,这就是我发现的。
    让我们先看看虚拟内存的使用情况:

    2: kd> !vm
    
    *** Virtual Memory Usage ***
    
    Physical Memory: 851420 ( 3405680 Kb)
    
    Page File: ??C:pagefile.sys
    
    Current: 3584000 Kb Free Space: 3568552 Kb
    
    Minimum: 3584000 Kb Maximum: 3584000 Kb
    
    Available Pages: 573277 ( 2293108 Kb)
    
    ResAvail Pages: 800628 ( 3202512 Kb)
    
    Locked IO Pages: 1067 ( 4268 Kb)
    
    Free System PTEs: 25102 ( 100408 Kb)
    
    Free NP PTEs: 335 ( 1340 Kb)
    
    Free Special NP: 0 ( 0 Kb)
    
    Modified Pages: 22 ( 88 Kb)
    
    Modified PF Pages: 22 ( 88 Kb)
    
    NonPagedPool Usage: 31369 ( 125476 Kb) ß Very high
    
    NonPagedPool Max: 31986 ( 127944 Kb)
    
    ********** Excessive NonPaged Pool Usage *****
    
    PagedPool 0 Usage: 19071 ( 76284 Kb)
    
    PagedPool 1 Usage: 735 ( 2940 Kb)
    
    PagedPool 2 Usage: 747 ( 2988 Kb)
    
    PagedPool 3 Usage: 720 ( 2880 Kb)
    
    PagedPool 4 Usage: 746 ( 2984 Kb)
    
    PagedPool Usage: 22019 ( 88076 Kb)
    
    PagedPool Maximum: 38912 ( 155648 Kb)
    
    ********** 3 pool allocations have failed **********

    所以我们可以看到NPP的使用率非常高,因为服务器使用的是/3GB开关,默认情况下NPP限制在128MB。我们需要确定哪些池标记与高NPP使用率相关:

    2: kd> !poolused /t2 2
    
    Sorting by NonPaged Pool Consumed
    
    Pool Used:
    
    NonPaged Paged
    
    Tag Allocs Used Allocs Used
    
    None 246479 50827424 0 0 call to ExAllocatePool
    
    MmCm 1198 18462512 0 0 Calls made to MmAllocateContiguousMemory , Binary: nt!mm

    很有趣,所以这个有问题的标签是“None”。这意味着这些分配是通过调用函数ExAllocatePool而不是ExAllocatePoolWithTag来完成的。ExAllocatePool已过时,不应再使用。
    现在,我需要找出哪个驱动程序在调用这个函数。首先,我需要知道ExAllocatePool住在哪里:

    2: kd> x nt!ExAllocatePool
    
    e0894d1f nt!ExAllocatePool
    
    Next, I need to search all the drivers to see which one is importing this function:
    
    2: kd> !for_each_module s-d @#Base @#End e0894d1f
    
    f50b8058 e0894d1f e0828e04 e089b708 e084011b .M..............

    看起来可疑地像导入表,让我们看看:

    2: kd> dps f50b8058
    
    f50b8058 e0894d1f nt!ExAllocatePool
    
    f50b805c e0828e04 nt!_wcsnicmp
    
    f50b8060 e089b708 nt!ExFreePoolWithTag
    
    f50b8064 e083e30a nt!KeInitializeEvent
    ...

    是的,那是导入表。您还可以通过检查标题(用!dh在模块基址并查找“Import Address Table Directory”)。
    如您所见,我们只有一个驱动程序导入ExAllocatePool。让我们看看这是哪个驱动程序:

    2: kd> !lmi f50b8058
    
    Loaded Module Info: [f50b8058]
    
    Module: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
    
    Base Address: f50b3000
    
    Image Name: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}.sys

    为了保护罪犯,我已经从上面显示的模块信息中删除了有罪的标识符。有趣的是,驱动程序名是一个GUID,而这个驱动程序不存在于磁盘上。这是因为驱动程序是在其父程序加载时动态创建的。
    将软件包被删除,服务器又恢复了正常。

  • 相关阅读:
    推荐书单
    图解Android
    图解Android
    图解Android
    图解Android
    图解Android
    图解Android
    个人博客平台 http://craft6.cn 上线
    数据库设计教程系列——相关知识点整理
    O2O研究系列——O2O知识思维导图整理
  • 原文地址:https://www.cnblogs.com/yilang/p/13581368.html
Copyright © 2020-2023  润新知