-
-
[原创]记一次内存泄露检查
-
发表于:
2021-5-9 14:36
8572
-
一个服务器程序,基于Windows IOCP实现,一直稳定运行,近期加入了一个异步HTTP处理后(WinHttp), 出现了轻微的内存泄露情况。
首先为服务器程序配置PageHeap,重启服务,对程序做FullMemoryDump取样,间隔一定时间,拿到多个样本。
使用gflags做PageHeap配置,如下图:
我此处收集了3个dmp, 分别查看其堆内存使用情况:
其中堆036c0000的内存提交大小在1个小时内,由1884KB增加到2072KB,其它堆的提交内存未有明显变化,因此可以怀疑内存泄露是在堆036c0000发生的,下面进一步查看其分配详情:
可以看到,内存块1ac和26c大小的分配是比较可疑的,一直处于一个递增的状态,选择1ac的块,继续跟进分配详情:
似乎是在Rsa私钥解密时,申请的内存,再选几个地址看后,发现在Rsa公钥加密时也会有类似的调用栈,Rsa算法使用的是OpenSSL3.0库,在之前的版本已经稳定运行了多时,此次版本升级,似乎没有涉及到SSL相关的代码,不过已经大概确定了位置,就写测试代码详细调试跟进一下吧。
(调试使用的OpenSSL库是重新下载的最新版编译的,发现依然有泄露,同时泄露的内存块大小变成了0x1a4)
栈跟踪不是很完整,00ed467c下段跟一下,此函数调用比较频繁,可以分两次操作:
首先,下在函数返回地址处,把返回值记录下来,如:bp 00ed4691 "r rax; g;",选择一个新增的泄露的内存地址,看是第几次分配的内存,我本地第11次分配时的内存未释放,(需要注意的是!heap看到的内存UsrPtr是包含块头结构的,需要减去块头大小才是记录下来的返回值,在我本地,这个大小是0x20)。
然后,下断bp 00ed4691 0n11 "r rax;", 创建新测试线程,断下后,查看堆栈如下:
进一步检查drbg_ctr_init,发现共有3个未释放指针,共占用(3 * 0x1a4)字节:
进一步回溯堆栈,发现了一处可疑操作:
跟进RAND_get0_public函数一探究竟:
同时,可以发现RAND_get0_private同RAND_get0_public,使用了同样的优化机制:
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-5-10 15:47
被Anakin Stone编辑
,原因: