Windbg调试c++内存泄漏

c++内存泄漏问题定位

     内存泄漏指的是直接操作内存分配构造函数(例如new,malloc,HeapAlloc)来获得堆内存后,但是没有释放而导致的泄漏问题。我们的行情服务器是一个长期运行在客户服务器上的应用程序,如果存在内存泄漏,那么当内存增长到某个值时,会极大地影响当前机器的性能,直至影响我们的行情服务程序,甚至由于内存已不够而导致的程序崩溃。因此我们需要掌握内存泄漏问题的基本调试技巧,本文对windbg调试内存泄漏问题做一个简单的介绍。
     以下面这个代码为例:
 

#include <iostream>
#include <windows.h>

int main()
{
	do 
	{
		char *p = new char[1024];
		Sleep(1);
	} while (1);
	
    std::cout << "Hello World!\n"; 
}

先进行windbg环境的配置:
1)配置windows符号服务器SRVd:\symbolshttp://msdl.microsoft.com/download/symbols
2)将当前程序的pdb文件路径加入到Windbg的Symbol File Path路径中
3)配置操作系统的标志,以便为内存泄漏的进程启用用户堆栈跟踪。可以通过安装Windbg自带的gflags.exe程序,通过命令“gflags.exe -i 20190718.exe +ust”来完成,20190718.exe是程序名(不用带路径,只用输入程序名即可)

 

准备工作完成后,开始进行一步步来调试: 1,    启动20190718.exe程序,使用Windbg的Attach To Process附加上去(或者通过Open Excutable直接打开) 
2,    附加进程后,输入“!heap –s”命令。-s代表统计信息,可以查看当前进程的所有堆分配信息:

 

此时只有一个堆02d40000(这个堆是CRT堆)。
 

 

3, F5让程序继续运行一会儿,然后中断(Windbg-Debug-Break菜单),再次输入“!heap –s”命令:

 

可以看到02d40000堆上分配的内存有增加。
 

 

4, 再输入“!heap -stat -h 02d40000”命令,查看正在增长的堆的堆统计信息:

 

-stat命令能够给出关于一个或者多个堆的使用统计信息,包括分配内存的大小,这个大小的堆块的个数以及总共的大小,最后是当前处于“busy”(占用)状态的堆块所占百分比。默认情况下,-stat按照总量大小来排序。

上面的快照显示正在分配的400(十六进制)大小的堆块有0x5acf个,且堆块所占百分比达到了99.77%,这些数据使我们推测大小为400(十六进制)bytes的内存存在泄漏的可能(也刚好是代码中分配的1024字节)。


5,    输入“!heap –flt s 400”,查看堆上所有大小为400的blocks信息:

 


6, 输入“!heap –p –a UserPtr”命令,UserPtr为上面的任何一个地址,比如!heap -p -a 047b8e70,显示地址047b8e70的调用堆栈信息:

从调用堆栈中可以看到,!main+0x0000001a地址处的代码可能导致内存泄漏。

 

 

7, 输入“lsa !main+0x0000001a”转到具体代码处:

参考文献:
1,《Windows高级调试》第九章第五节
2, https://www.codeproject.com/Articles/31382/Memory-Leak-Detection-Using-Windbg

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值