当前位置:   article > 正文

ProcExp软件运行内存过高分析

procexp

ProcExp软件运行内存过高分析

ProcExp是微软提供的一款进程浏览器工具,他是对任务管理器的增强;通过它我们可以查看系统的运行情况,包括但不限于:

  1. 系统运行的进程,并且包括进程的其他信息,例如加载的Dll,句柄,内存等。
  2. 整体系统的性能信息,包括CPU,内存,磁盘等。

最近在使用这个软件的时候发现该软件占用内存非常大,导致本人16GB的菜鸡电脑运行非常卡慢,如下示意图:
在这里插入图片描述

这里ProxExp占用了1GB以上的内存,这个绝对是异常的情况;理论来说作为SysinternalsSuite来说应该是不会产生内存泄漏这种通用性的问题,那么是什么导致ProxExp占用这么高的内存呢?本文来分析一下具体原因。

1. 内存概览

作为开发人员,这里直接使用WinDbg来排查(当然还可以使用一些更加简单的工具)。因为大部分情况下,占用内存太高都是堆内存使用过高导致的,我们直接查看堆内存的占用情况:

0:005> !heap -s


************************************************************************************************************************
                                              NT HEAP STATS BELOW
************************************************************************************************************************
NtGlobalFlag enables following debugging aids for new heaps:
    stack back traces
LFH Key                   : 0x6f02eff3e12c8d31
Termination on corruption : ENABLED
          Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                            (k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
000001eaf44f0000 08000002   49132  43604  48740    709   583     7    1     1c   LFH
000001eaf2ad0000 08008000      64      4     64      2     1     1    0      0      
000001eaf4480000 08001002    3516   1544   3124   1360    25     3    0      0   LFH
    External fragmentation  88 % (25 free blocks)
000001eaf5fb0000 08001002    1472    100   1080     10    10     2    0      0   LFH
000001eaf64c0000 08001002     452     36     60      6     5     1    0      0   LFH
000001eaf6830000 08001002     452     32     60      7     4     1    0      0   LFH
000001eac26e0000 08001002     452     48     60      7     4     1    0      0   LFH
-------------------------------------------------------------------------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

从上面来看,我们在堆上面分配的内存没有任何问题,虚拟内存只有48MB,这对于一个在Windows11环境下面运行的UI程序来说是不算多的。

但是我们这里可以看到有一个虚拟内存块,那么是否是这个虚拟内存块导致的内存太大了呢?我们看一下000001eaf44f0000这个堆上面内存的情况,如下:

0:005> !heap -stat -h 000001eaf44f0000 
 heap @ 000001eaf44f0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    40000000 1 - 40000000  (96.76)
    3c00 223 - 803400  (0.76)
    5d0 1202 - 68aba0  (0.62)
    1e00 118 - 20d000  (0.19)
    d8080 1 - d8080  (0.08)
    d65a0 1 - d65a0  (0.08)
    d3df8 1 - d3df8  (0.08)
    360 360 - b6400  (0.07)
    b6374 1 - b6374  (0.07)
    6c8 19b - ae318  (0.06)
    8d80 10 - 8d800  (0.05)
    28 301c - 78460  (0.04)
    1436 2b - 36512  (0.02)
    48 ab5 - 302e8  (0.02)
    800 58 - 2c000  (0.02)
    2bca3 1 - 2bca3  (0.02)
    30 e98 - 2bc80  (0.02)
    143a 22 - 2afb4  (0.02)
    2ad08 1 - 2ad08  (0.02)
    29180 1 - 29180  (0.02)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

果然是的,这里分配了一块很大的内存40000000,这个内存大小如下:

0:005> ? 40000000
Evaluate expression: 1073741824 = 00000000`40000000
  • 1
  • 2

这一块内存就有1GB往上,那么整个ProcExp工具占用内存过高就是这块内存太大导致的。

2. 问题排查

从上面内存分析,我们似乎可以得出ProxExp这个工具真的有BUG,导致内存占用够大,下面我们查一下具体原因。

首先,我们对内存分配的函数下断点,查找到分配这块内存的地方:

bp ntdll!NtAllocateVirtualMemory ".if (qwo(@r9) >= 0x40000000){} .else{gc;}"
  • 1

运行程序,顺利在断点处中断了程序的运行,此时堆栈信息如下:

0:000> kb
 # RetAddr               : Args to Child                                                           : Call Site
00 00007ffa`6d2662fe     : 00000000`00000000 00007ffa`6d2ee4f8 000004f0`fffffb30 000004d0`fffffb30 : ntdll!NtAllocateVirtualMemory
01 00007ffa`6d20c0ff     : 00000199`0aa90000 00000000`00000000 00000000`0000a000 00000023`14efea38 : ntdll!RtlpHpAllocVirtBlockCommitFirst+0x56
02 00007ffa`6d20929c     : 00000199`0aa90000 00000199`00000002 00000000`40000020 00000000`40000068 : ntdll!RtlpAllocateHeap+0xf9f
03 00007ff7`46183fe8     : 00000000`00000001 00000000`40000000 00000000`00009720 00000000`00000000 : ntdll!RtlpAllocateHeapInternal+0x6ac
04 00007ff7`46144333     : 00000000`00000001 00000000`00000000 00000000`00000001 00000000`00000000 : procexp64+0x103fe8
05 00007ff7`46144a89     : 00000023`28618060 00000199`0c660000 00000000`0000043c 00000000`00009720 : procexp64+0xc4333
06 00007ff7`460f3ccd     : 00007ff7`46080000 00007ff7`46229580 00000000`00009720 00000000`0000000a : procexp64+0xc4a89
07 00007ff7`4615dab3     : 00007ff7`461f9580 00007ff7`46229580 00000000`00009720 00007ff7`46229580 : procexp64+0x73ccd
08 00007ff7`46161d0a     : 00000000`00000000 00000000`0000000a 00000000`00000000 00000000`00000000 : procexp64+0xddab3
09 00007ffa`6b0653e0     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : procexp64+0xe1d0a
0a 00007ffa`6d1e485b     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x10
0b 00000000`00000000     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2b
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

通过NtAllocateVirtualMemory参数查看分配内存的请求大小,如下:

0:000> dq @r9 L1
00000023`14efea10  00000000`4000b068
  • 1
  • 2

这正是我们上面分析的大内存,因此证明这个堆栈是正确的。我们查看ProcExp的反汇编代码,发现分配内存的代码如下:
在这里插入图片描述

通过MessageBox处的日志"Insufficient system resources to get handle information"我们可以猜测出,这里是ProxExp在获取句柄信息的时候分配了太多的内存导致的。产生这个问题有两个原因:

  1. ProcExp工具代码有BUG。
  2. 真实需要那么多的内存处理句柄信息。

下面我们分析一下具体是那个原因导致的。

3. 原因分析

通过上述的反汇编代码我们可以得知并猜测两个原因:

  1. ProxExp正确获取句柄信息,并且代码看起来没有什么问题。
  2. ProxExp这个工具使用非常久了,应该不会存在这种BUG。

那么我们直接来排查系统应该有那么多句柄信息需要获取,我们使用ProxExp查看一下系统中进程的句柄信息,使用如下选项:

在这里插入图片描述

根据Handles列排序之后,我们可以发现一个进程使用句柄非常多,如下:
在这里插入图片描述

这个进程完整路径为"C:\Program Files\ASUS\AacMB\Aac3572MbHal_x86.exe",这个是华硕的一个进程,我用的华硕的主板,可能是默认安装的程序,如下:
在这里插入图片描述

我们把这个进程结束掉,然后重启ProcExp,进程内存正常,如下:
在这里插入图片描述

至此,我们分析了该问题产生的原因,是因为Aac3572MbHal_x86.exe分配句柄太多导致的;至于Aac3572MbHal_x86.exe分配句柄太多的BUG,不再此深入分析,卸载该软件即可。

4. 总结

ProcExp软件运行内存过高这个问题分析起来虽然不困难,但是这个是作为一个软件问题分析的典型,在这里文章记录一下相关过程,如果有更好的排查思路,希望大家能够指正和交流。

当然这也是软件开发中一个典型的城门失火,殃及鱼池的案例。Aac3572MbHal_x86.exe泄漏了太多的句柄,没有被使用者发现,但是殃及了ProcExp使用了太多的内存,从而引发的一系列问题。

那么是否真的就是Aac3572MbHal_x86.exe这款软件自己的BUG导致句柄的泄漏,还是另外其他的模块导致的呢?这里并不做详细分析,也许Aac3572MbHal_x86.exe并不是真正的源头呢!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/573394
推荐阅读
相关标签
  

闽ICP备14008679号