Windbg 分析内存泄漏

本文提供了一种详细的内存泄漏诊断方法,包括设置调试标志、使用特定命令进行内存泄漏检测和定位,以及如何通过windbg命令行工具进行深入分析。通过实例代码演示了如何在程序中实现内存泄漏检测,并解释了如何解析windbg输出来识别和解决内存泄漏问题。

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

1. 首先添加这样的一段代码到头文件中。

#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif  // _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif  // _DEBUG

2. 在程序开始处,一般是main中

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);

3. 将windbg路径添加到path中

4. gflags /i mem_leak.exe +ust

5. windbg -g mem_leak.exe

mem_leak退出之后会在windbg中打印:

CommandLine: mem_leak.exe
Symbol search path is: srv*D:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
ModLoad: 00400000 0041d000   mem_leak.exe
ModLoad: 772a0000 773dc000   ntdll.dll
ModLoad: 769e0000 76ab4000   C:\Windows\system32\kernel32.dll
ModLoad: 75540000 7558a000   C:\Windows\system32\KERNELBASE.dll
ModLoad: 5b5d0000 5b6f1000   C:\Windows\WinSxS\x86_microsoft.vc80.debugcrt_1fc8b3b9a1e18e3b_8.0.50727.6195_none_e4a70117006762dd\MSVCR80D.dll
ModLoad: 77420000 774cc000   C:\Windows\system32\msvcrt.dll
ModLoad: 5cbe0000 5ccde000   C:\Windows\WinSxS\x86_microsoft.vc80.debugcrt_1fc8b3b9a1e18e3b_8.0.50727.6195_none_e4a70117006762dd\MSVCP80D.dll
Detected memory leaks!
Dumping objects ->
f:\study\code\mem_leak\mem_leak\mem_leak.cpp(29) : {171} client block at 0x01509250, subtype 0, 100 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
Object dump complete.
eax=00000000 ebx=00000000 ecx=0012fe5c edx=00000020 esi=77377380 edi=77377340
eip=772e7094 esp=0012feac ebp=0012fec8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCallRet:
772e7094 c3              ret




6. 使用!heap命令。使用!heap -p -a <泄漏的地址>,这里是0x01509250

0:000> !heap -p -a 0x01509250
    address 01509250 found in
    _HEAP @ 1500000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        01509218 0014 0000  [00]   01509230    00088 - (busy)
        Trace: 179798
        7731ddac ntdll!RtlAllocateHeap+0x00000274
        5b5e2f4c MSVCR80D!_heap_alloc_base+0x0000005c
        5b5eae15 MSVCR80D!_heap_alloc_dbg+0x000001f5
        5b5eaba9 MSVCR80D!_nh_malloc_dbg+0x00000019
        5b5d13bd MSVCR80D!operator new+0x0000001d
        5b5d14e9 MSVCR80D!operator new[]+0x00000019
*** WARNING: Unable to verify checksum for mem_leak.exe
        411560 mem_leak!ThreadProc+0x00000060
        76a2ed6c kernel32!BaseThreadInitThunk+0x0000000e
        7730377b ntdll!__RtlUserThreadStart+0x00000070
        7730374e ntdll!_RtlUserThreadStart+0x0000001b




到这里我们的这次内存泄漏的分析就结束了。大部分这样的泄漏都可以通过这样的方式进行解决。
还有一些是那种内存不断增加泄漏都的内存使用的是
定时使用!heap -s 命令查看泄漏情况.然后使用!heap -stat -h **.
!heap -flt -s **
最后还是!heap -p -a查看堆栈
还有一种是使用_DPH_BLOCK_INFORMATION信息进行的详见:http://book.51cto.com/art/200812/102533.htm


大体的方法就是这些了。

测试代码:

// mem_leak.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <iostream>

#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif  // _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif  // _DEBUG

using namespace std;
ULONG WINAPI ThreadProc(LPVOID)
{

	cout<<"thread running"<<endl;
	char* pBuffer = new char[100];
	

	while(1)
	{
		Sleep(1000);
	}

	cout<<"thread exit"<<endl;


	return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);

	cout<<"intput q to teminate thread"<<endl;
	HANDLE hthread = ::CreateThread(NULL,NULL,ThreadProc,NULL,NULL,NULL);
	char ch;
	cin>>ch;

	if(ch != 'q')
	{
		cin.clear();
		cin >> ch;
	}

	TerminateThread(hthread,0);
	

	//system("pause");

	return 0;
}




                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值