memory leak

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>

#include <crtdbg.h>

下面的语句放在主函数开头,就不用每个出口都写上_CrtDumpMemoryLeaks(); 了

#ifdef _DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF| _CRTDBG_LEAK_CHECK_DF);
#endif

 

how to:dbghelp, dr.watson

如何捕捉程序异常

使用dbghelp获取调用堆栈

 

#include <windows.h>
#include <stdio.h>
#include <dbghelp.h>

#pragma comment( lib, "dbghelp.lib" )

void dump_callstack( CONTEXT *context )
{
	STACKFRAME sf;
	memset( &sf, 0, sizeof( STACKFRAME ) );

	sf.AddrPC.Offset = context->Eip;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrStack.Offset = context->Esp;
	sf.AddrStack.Mode = AddrModeFlat;
	sf.AddrFrame.Offset = context->Ebp;
	sf.AddrFrame.Mode = AddrModeFlat;

	DWORD machineType = IMAGE_FILE_MACHINE_I386;

	HANDLE hProcess = GetCurrentProcess();
	HANDLE hThread = GetCurrentThread();

	for( ; ; )
	{
		if( !StackWalk(machineType, hProcess, hThread, &sf, context, 0, SymFunctionTableAccess, SymGetModuleBase, 0 ) )
		{
			break;
		}

		if( sf.AddrFrame.Offset == 0 )
		{
			break;
		}
		BYTE symbolBuffer[ sizeof( SYMBOL_INFO ) + 1024 ];
		PSYMBOL_INFO pSymbol = ( PSYMBOL_INFO ) symbolBuffer;

		pSymbol->SizeOfStruct = sizeof( symbolBuffer );
		pSymbol->MaxNameLen = 1024;

		DWORD64 symDisplacement = 0;
		if( SymFromAddr( hProcess, sf.AddrPC.Offset, 0, pSymbol ) )
		{
			printf( "Function : %s\n", pSymbol->Name );
		}
		else
		{
			printf( "SymFromAdd failed!\n" );
		}

		IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
		DWORD dwLineDisplacement;

		if( SymGetLineFromAddr( hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo ) )
		{
			printf( "[Source File : %s]\n", lineInfo.FileName ); 
			printf( "[Source Line : %u]\n", lineInfo.LineNumber ); 
		}
		else
		{
			printf( "SymGetLineFromAddr failed!\n" );
		}
	}
}

DWORD excep_filter( LPEXCEPTION_POINTERS lpEP )
{
	/** init dbghelp.dll
	if( SymInitialize( GetCurrentProcess(), NULL, TRUE ) )
	{
		printf( "Init dbghelp ok.\n" );
	}

	dump_callstack( lpEP->ContextRecord );

	if( SymCleanup( GetCurrentProcess() ) )
	{
		printf( "Cleanup dbghelp ok.\n" );
	}

	return EXCEPTION_EXECUTE_HANDLER;
}

void func1( int i )
{
	int *p = 0;
	*p = i;
}

void func2( int i )
{
	func1( i - 1 );
}

void func3( int i )
{
	func2( i - 1 );
}

void test( int i )
{
	func3( i - 1 );
}

int main()
{
	__try
	{
		test( 10 );
	}
	__except( excep_filter( GetExceptionInformation() ) )
	{
		printf( "Some exception occures.\n" );
	}

	return 0;
}

 执行结果

Init dbghelp ok.
Function : func1
[Source File : g:\tmp\test_mem_leak\test_getexceptioninformation\test.cpp]
[Source Line : 87]
Function : func2
[Source File : g:\tmp\test_mem_leak\test_getexceptioninformation\test.cpp]
[Source Line : 92]
Function : func3
[Source File : g:\tmp\test_mem_leak\test_getexceptioninformation\test.cpp]
[Source Line : 97]
Function : test
[Source File : g:\tmp\test_mem_leak\test_getexceptioninformation\test.cpp]
[Source Line : 102]
Function : main
[Source File : g:\tmp\test_mem_leak\test_getexceptioninformation\test.cpp]
[Source Line : 109]
Function : __tmainCRTStartup
[Source File : f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c]
[Source Line : 582]
Function : mainCRTStartup
[Source File : f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c]
[Source Line : 399]
Function : RegisterWaitForInputIdle
SymGetLineFromAddr failed!
Cleanup dbghelp ok.
Some exception occures.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值