使用Windbg定位内存泄露

本文介绍了如何使用Windbg来定位内存泄露。在场景一中,针对Debug版本程序,通过在程序退出时获取内存泄露报告来定位。而在场景二中,即使不是Debug版本,也可以通过attach/detach程序,对比不同时间点的堆内存使用情况,找出内存增长明显的堆,从而有效定位内存泄露位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网上看了两篇文章,整理一下,大致内容如下:

 

场景一:运行Debug版本程序,用Windbg attach 上去,等程序退出时,基于内存泄露报告,定位内存泄露的位置。

 

首先使用windbg工具gflags.exe设置内存启动跟踪内存泄露进程的user stack

启动方法就是运行下面指令<span style="BACKGROUND-COLOR: #ff6666">gflags.exe /i test.exe +ust</span><span style="BACKGROUND-COLOR: #ffffff"> <span style="color:#ff0000;">需要通过gflags.exe工具打开开关,才能调试内存泄露!
</span>
</span>等价于HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options,命令“gflags.exe /i test.exe +ust”实际上就是在该路径下创建一个子键“test.exe”并创建一个名为GlobalFlag内容为0x00001000的REG_DWORD值。

使用windbg加载test.exe,运行关闭时windbg中会提示内存泄露

normal block at 0x026A5F98, 4000 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.
可以发现地址0x026A5F98就是内存泄漏的地址泄漏4000个字节

通过!heap命令对该地址进行分析可以发现具体的调用堆栈

0:000> <span style="BACKGROUND-COLOR: #ff99ff">!heap -p -a 0x026A5F98
</span>    address 026a5f98 found in
    _HEAP @ 14f0000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        026a5f60 01fc 0000  [00]   026a5f78    00fc4 - (busy)
        77a1b234 ntdll!RtlAllocateHeap+0x00000274
        584d7743 MSVCR100D!_heap_alloc_base+0x00000053
        584e5d8c MSVCR100D!_heap_alloc_dbg_impl+0x000001fc
        584e5b2f MSVCR100D!_nh_malloc_dbg_impl+0x0000001f
        584e5adc MSVCR100D!_nh_malloc_dbg+0x0000002c
        584e5a91 MSVCR100D!_malloc_dbg+0x00000021
        58694dd6 mfc100ud!operator new+0x00000026
        58694e6a mfc100ud!operator new[]+0x0000001a
        58694768 mfc100ud!operator new[]+0x00000018
*** WARNING: Unable to verify checksum for SendMsgEx.exe
        2a3c25 <span style="BACKGROUND-COLOR: #ff99ff">SendMsgEx!CSendMsgExDlg::Thread1Proc</span>+0x00000055
        767c1174 kernel32!BaseThreadInitThunk+0x0000000e
        779fb3f5 ntdll!__RtlUserThreadStart+0x00000070
        779fb3c8 ntdll!_RtlUserThreadStart+0x0000001b
可以发现内存泄漏的地址在CSendMsgExDlg::Thread1Proc这个地址里面调用了new[]导致内存泄漏

DWORD WINAPI CSendMsgExDlg::Thread1Proc(__in  LPVOID lpParameter)
{
    INT *pVal = new INT[1000];
        //..................
}


结论:场景一适用于Debug版本程序,而且需要在程序退出时才能定位泄露

 

场景二:程序运行一段时间,用Windbg attach上去,查看堆内存使用情况;detach 让程序继续运行;过一段时间再 attac

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值