内存泄漏检测

来源:互联网 发布:上海音乐学院网络报名 编辑:程序博客网 时间:2024/05/19 19:43

console (控制台)  内存检测可以以下这样最简单的方法

 

// 用法:按 F5 调试,如果有内存泄漏的情况,用鼠标双击"输出"那里的信息,会定位到那一语句泄漏//       或按 F4 也能定位到内存泄漏的语句    by benben 2012.12.28#define _CRTDBG_MAP_ALLOC#include<stdlib.h>#include<crtdbg.h>#define new new( _CLIENT_BLOCK, __FILE__, __LINE__)// 内存检测的类class MemLeakDetectTest_ben{public:inline ~MemLeakDetectTest_ben(){_CrtDumpMemoryLeaks();}};MemLeakDetectTest_ben memLeakDetect; // 定义一个全局内存检测的对象// 演示内存泄漏的函数void MemLeakFunc(){double *pD = new double;}int _tmain(int argc, _TCHAR* argv[]){MemLeakFunc();int* pInt = new int[100];return 0;}


==============================================================================================================================

  

 

方法二:可参考 http://www.codeproject.com/Articles/8448/Memory-Leak-Detection# 

头文件:

/************************************************************* Author: David A. Jones File Name: MemLeakDetect.h Date: July 30, 2004 Synopsis: A trace memory feature for source code to trace andfind memory related bugs.  Future:1) Memory corruption2) Freeing memory without allocating3) Freeing memory twice4) Not Freeing memory at all5) over running memory boundardiesJuly 2009: tim.s.stevens@bt.com (UNICODE/ANSI 32 bit only, more secure CRT with VS 2008).Feb  2011: Doug Rogers <rogers.doug@gmail.com>, igor.jambrek@gmail.com, OfekSH & tim. (Compiles as 64 & 32 bit).Based on http://www.codeproject.com/cpp/MemLeakDetect.asp****************************************************************//*Compiles clean in Visual Studio 2008 SP1 in 32 & 64 UNICODE and MultiByte builds.By default, disabled in Release mode, since it relies on the Debug MS Runtime DLLs, the licence terms of which onlyallow redistribution in Release mode. However, if you do want to use it in Release mode, then comment out the"#ifdef _DEBUG" lines that guard the complete MemLeakDetect.h & .cpp files, and link against the Debug runtimes(e.g. /MTd instead of /MT) in Release mode.Please don't use precompiled headers for this file.To catch most malloc/free or new/delete leaks, simply add this block of code (& #define MEMORY_LEAK_CHECK)at the application level:#ifdef _DEBUG#ifdef MEMORY_LEAK_CHECK#include "MemLeakDetect.h"static CMemLeakDetect memLeakDetect;#endif#endifA typical leak might be:int *pfoo = new int[1000];Then forgetting to dodelete [] pfoo;Then when running under a debugger, if there is a leak, you'll get this kind of output in the Output pane.You'll also get files with names like "mldetector-(AppName.exe)_Feb16-2011__21-53-43.log"written to your %TEMP% directory:Memory Leak(1)------------------->Memory Leak <0xBC> bytes(86) occurance(0)c:\code\ta2svn\sandbox\pjh\software\common\memleakdetect.cpp(201): 0x0044B7C3->CMemLeakDetect::addMemoryTrace()c:\code\ta2svn\sandbox\pjh\software\common\memleakdetect.cpp(140): 0x0044B4B2->catchMemoryAllocHook()0x0012D874->_malloc_dbg()0x0012D874->_malloc_dbg()0x0012D874->_malloc_dbg()0x0012D874->malloc()0x0012D874->??2@YAPAXI@Z()f:\dd\vctools\crt_bld\self_x86\crt\src\newaop.cpp(7): 0x004B4D1E->operator new[]()c:\code\ta2svn\sandbox\pjh\software\hw_app\hw_app.cpp(145): 0x00442276->wmain()f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c(579): 0x004B56C8->__tmainCRTStartup()f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c(399): 0x004B550F->wmainCRTStartup()0x0012D874->RegisterWaitForInputIdle()-----------------------------------------------------------Total 1 Memory Leaks: 86 bytes Total Alocations 276You can then double-click in the Output pane on the leak ((145) in the example above) and be taken to the source linewhich caused the leak.*/#include "stdafx.h"#if !defined(MEMLEAKDETECT_H)#define MEMLEAKDETECT_H#ifdef _DEBUG#define _CRTDBG_MAP_ALLOC#include <map>#define _CRTBLD#include <windows.h>#include <..\crt\src\dbgint.h>#include <ImageHlp.h>#include <crtdbg.h>#pragma comment( lib, "imagehlp.lib" )using namespace std;// if you want to use the custom stackwalker otherwise// comment this line out#define MLD_CUSTOMSTACKWALK1//#define MLD_MAX_NAME_LENGTH256#define MLD_MAX_TRACEINFO63#define MLD_TRACEINFO_EMPTY_T("")#define MLD_TRACEINFO_NOSYMBOL_T("?(?)")#ifdef  MLD_CUSTOMSTACKWALK#define MLD_STACKWALKERsymStackTrace2#else#define MLD_STACKWALKERsymStackTrace#endif#define AfxTrace MyTrace#ifndef _WIN64typedef DWORD ADDR;typedef PIMAGEHLP_SYMBOL IMAGE_SYM;typedef IMAGEHLP_LINE IMAGE_LN;#elsetypedef DWORD64 ADDR;typedef PIMAGEHLP_SYMBOL64 IMAGE_SYM;typedef IMAGEHLP_LINE64 IMAGE_LN;#endifclass CMemLeakDetect{public:typedef struct {ADDRESSaddrPC;ADDRESSaddrFrame;} STACKFRAMEENTRY;typedef struct tagAllocBlockInfo{//Added constructor to zero memory - thanks to bugfix from OfekSH.tagAllocBlockInfo() { ZeroMemory(traceinfo, sizeof(traceinfo) ); }void*address; size_tsize;TCHARfileName[MLD_MAX_NAME_LENGTH];DWORDlineNumber;DWORDoccurance;STACKFRAMEENTRYtraceinfo[MLD_MAX_TRACEINFO];} AllocBlockInfo;//typedef int POSITION;typedef map<LPVOID, AllocBlockInfo>KEYMAP;typedef map<LPVOID, AllocBlockInfo>::iteratorPOSITION;typedef pair<LPVOID, AllocBlockInfo>KEYVALUE;class CMapMem{public:KEYMAPm_Map;POSITIONm_Pos;inline BOOL Lookup(LPVOID pAddr,  AllocBlockInfo& aInfo) { m_Pos = m_Map.find(pAddr);//if (m_Pos == m_Map.end()){return FALSE;}//pAddr = m_Pos->first;aInfo = m_Pos->second;return TRUE;};inline POSITION end() { return m_Map.end(); };inline void RemoveKey(LPVOID pAddr) { m_Map.erase(pAddr);};inline void RemoveAll() {m_Map.clear();};void SetAt(LPVOID pAddr, AllocBlockInfo& aInfo) {m_Map[pAddr] = aInfo;};inline POSITION GetStartPosition() { POSITION pos = m_Map.begin(); return pos;};inline void GetNextAssoc(POSITION& pos, LPVOID& rAddr, AllocBlockInfo& aInfo) {rAddr = pos->first;aInfo = pos->second;pos++;};void InitHashTable(int preAllocEntries, BOOL flag) { preAllocEntries= NULL; flag= NULL;};};CMemLeakDetect();~CMemLeakDetect();void Init();void End();void addMemoryTrace(void* addr,  size_t asize,  TCHAR *fname, DWORD lnum);void redoMemoryTrace(void* addr,  void* oldaddr, size_t asize,  TCHAR *fname, DWORD lnum);void removeMemoryTrace(void* addr, void* realdataptr);void cleanupMemoryTrace();void dumpMemoryTrace();////CMap<LPVOID, LPVOID, AllocBlockInfo, AllocBlockInfo> m_AllocatedMemoryList;CMapMem m_AllocatedMemoryList;DWORD memoccurance;bool  isLocked;//private:typedef USHORT (WINAPI *CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG);HMODULE m_k32;CaptureStackBackTraceType m_func;BOOL initSymInfo(TCHAR* lpUserPath);BOOL cleanupSymInfo();void symbolPaths( TCHAR* lpszSymbolPaths);void symStackTrace(STACKFRAMEENTRY* pStacktrace);void symStackTrace2(STACKFRAMEENTRY* pStacktrace);BOOL symFunctionInfoFromAddresses(ADDR fnAddress, ADDR stackAddress, TCHAR *lpszSymbol, UINT BufSizeTCHARs);BOOL symSourceInfoFromAddress(ADDR address, TCHAR* lpszSourceInfo);BOOL symModuleNameFromAddress(ADDR address, TCHAR* lpszModule);HANDLEm_hProcess;PIMAGEHLP_SYMBOLm_pSymbol;DWORDm_dwsymBufSize;};#endif#endif

 

 

源文件:


/************************************************************* Author: David A. Jones File Name: MemLeakDetect.h Date: July 30, 2004 Synopsis A trace memory feature for source code to trace andfind memory related bugs. ****************************************************************/// See MemLeakDetect.h for full history.// Based on http://www.codeproject.com/cpp/MemLeakDetect.asp#include "stdafx.h"#ifdef _DEBUG#include <tchar.h>#include "MemLeakDetect.h"#include <fstream>#include <time.h>#include <Psapi.h>// Only needed for GetModuleBaseName().#pragma comment(lib, "Psapi.lib")// Only needed for GetModuleBaseName().//#pragma warning(disable:4312)// 'type cast' : conversion from 'long' to 'void *' of greater size//#pragma warning(disable:4313)//#pragma warning(disable:4267)#pragma warning(disable:4100)// Unreferenced formal parameter.static CMemLeakDetect*g_pMemTrace= NULL;static _CRT_ALLOC_HOOKpfnOldCrtAllocHook= NULL;static int catchMemoryAllocHook(intallocType,  void*userData,  size_t size,  intblockType,  longrequestNumber,   const unsigned char*filename, // Can't be UNICODE intlineNumber) ;static int MyTrace(LPCTSTR lpszFormat, ...);static void DeleteOldTempFiles(const TCHAR dir[], const TCHAR type[], int DaysAge);static int MyTrace(LPCTSTR lpszFormat, ...){ va_list args;va_start( args, lpszFormat);#ifndef UNICODEchar buffer[1024];vsprintf_s( buffer, lpszFormat, args );return _CrtDbgReport(_CRT_WARN,NULL,NULL,NULL,buffer);#elseTCHAR buffer[1024];vswprintf_s( buffer, lpszFormat, args );char fmtbuf[1024] ;WideCharToMultiByte(CP_ACP, 0, buffer, -1,fmtbuf, 1024, NULL, NULL ) ;return _CrtDbgReport(_CRT_WARN,NULL,NULL,NULL,fmtbuf);#endif}static int catchMemoryAllocHook(intallocType,  void*userData,  size_t size,  intblockType,  longrequestNumber,   const unsigned char*filename,  // Can't be UNICODE intlineNumber){_CrtMemBlockHeader *pCrtHead;long prevRequestNumber;#ifdef UNICODEwchar_t Wname[1024] ;Wname[0] = L'\0' ;#endif// internal C library internal allocationsif ( blockType == _CRT_BLOCK ){return( TRUE );}// check if someone has turned off mem tracingif  ((( _CRTDBG_ALLOC_MEM_DF & _crtDbgFlag) == 0) && (( allocType== _HOOK_ALLOC)|| ( allocType== _HOOK_REALLOC))){if (pfnOldCrtAllocHook){pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);}return TRUE;}// protect if mem trace is not initializedif (g_pMemTrace == NULL){if (pfnOldCrtAllocHook){pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);}return TRUE;}// protect internal mem trace allocsif (g_pMemTrace->isLocked){if (pfnOldCrtAllocHook){pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);}return( TRUE);}// lock the functiong_pMemTrace->isLocked = true;//#ifdef UNICODEint len ;if (NULL != filename){len = (int)strlen((char *)filename) + 1 ;MultiByteToWideChar(CP_ACP, 0, (char *)filename, len, Wname, len) ;}elselen = 0 ;#else#define Wname (char*)filename#endifif (allocType == _HOOK_ALLOC){g_pMemTrace->addMemoryTrace((void *) requestNumber, size, Wname, lineNumber);}elseif (allocType == _HOOK_REALLOC){if (_CrtIsValidHeapPointer(userData)){pCrtHead = pHdr(userData);prevRequestNumber = pCrtHead->lRequest;//if (pCrtHead->nBlockUse == _IGNORE_BLOCK){if (pfnOldCrtAllocHook){pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);}goto END;}   g_pMemTrace->redoMemoryTrace((void *) requestNumber, (void *) prevRequestNumber, size, Wname, lineNumber);}}elseif (allocType == _HOOK_FREE){if (_CrtIsValidHeapPointer(userData)){pCrtHead = pHdr(userData);requestNumber = pCrtHead->lRequest;//if (pCrtHead->nBlockUse == _IGNORE_BLOCK){if (pfnOldCrtAllocHook){pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);}goto END;}   g_pMemTrace->removeMemoryTrace((void *) requestNumber, userData);}}END:// unlock the functiong_pMemTrace->isLocked = false;return TRUE;}void CMemLeakDetect::addMemoryTrace(void* addr,  size_t asize,  TCHAR *fname, DWORD lnum){AllocBlockInfo ainfo;//if (m_AllocatedMemoryList.Lookup(addr, ainfo)){// already allocatedAfxTrace(_T("ERROR!CMemLeakDetect::addMemoryTrace() Address(0x%p) already allocated\n"), addr);return;}//ainfo.address= addr;ainfo.lineNumber= lnum;ainfo.size= asize;ainfo.occurance= memoccurance++;MLD_STACKWALKER(&ainfo.traceinfo[0]);//if (fname)_tcsncpy_s(&ainfo.fileName[0], MLD_MAX_NAME_LENGTH, fname, MLD_MAX_NAME_LENGTH);else  ainfo.fileName[0] = 0;//m_AllocatedMemoryList.SetAt(addr, ainfo);};void CMemLeakDetect::redoMemoryTrace(void* addr,  void* oldaddr, size_t asize,  TCHAR *fname, DWORD lnum){AllocBlockInfo ainfo;if (m_AllocatedMemoryList.Lookup(oldaddr,(AllocBlockInfo &) ainfo)){m_AllocatedMemoryList.RemoveKey(oldaddr);}else{AfxTrace(_T("ERROR!CMemLeakDetect::redoMemoryTrace() didnt find Address(0x%08X) to free\n"), oldaddr);}//ainfo.address= addr;ainfo.lineNumber= lnum;ainfo.size= asize;ainfo.occurance= memoccurance++;MLD_STACKWALKER(&ainfo.traceinfo[0]);//if (fname)_tcsncpy_s(&ainfo.fileName[0], MLD_MAX_NAME_LENGTH, fname, MLD_MAX_NAME_LENGTH);else  ainfo.fileName[0] = 0;m_AllocatedMemoryList.SetAt(addr, ainfo);};void CMemLeakDetect::removeMemoryTrace(void* addr, void* realdataptr){AllocBlockInfo ainfo;//if (m_AllocatedMemoryList.Lookup(addr,(AllocBlockInfo &) ainfo)){m_AllocatedMemoryList.RemoveKey(addr);}else{   //freeing unallocated memoryAfxTrace(_T("ERROR!CMemLeakDetect::removeMemoryTrace() didnt find Address(0x%08X) to free\n"), addr);}};void CMemLeakDetect::cleanupMemoryTrace(){m_AllocatedMemoryList.RemoveAll();};void CMemLeakDetect::dumpMemoryTrace(){POSITIONpos;LPVOIDaddr;AllocBlockInfoainfo;TCHARbuf[MLD_MAX_NAME_LENGTH];TCHARfileName[MLD_MAX_NAME_LENGTH];TCHARsymInfo[MLD_MAX_NAME_LENGTH];TCHARsrcInfo[MLD_MAX_NAME_LENGTH];size_ttotalSize= 0;intnumLeaks= 0;STACKFRAMEENTRY*p= 0;ofstream myfile;#ifdef UNICODEchar dest[1024] ;#endifstruct tm timeinfo;__time64_t long_time;_time64(&long_time);// Convert to local time._localtime64_s(&timeinfo, &long_time);TCHAR TempDir[MAX_PATH];TCHAR ProcName[MAX_PATH];GetTempPath(MAX_PATH, TempDir);ProcName[0] = _T('\0');GetModuleBaseName(GetCurrentProcess(), NULL, ProcName, sizeof(ProcName)/sizeof(TCHAR));_stprintf_s(fileName, MLD_MAX_NAME_LENGTH, _T("%smldetector-(%s)_"), TempDir, ProcName); _tcsftime(buf,MLD_MAX_NAME_LENGTH, _T("%b%d-%Y__%H-%M-%S.log"),&timeinfo);_tcscat_s(fileName,MLD_MAX_NAME_LENGTH, buf);myfile.open (fileName); DeleteOldTempFiles(TempDir, _T("mldetector-(*.log"), 7);//_tcscpy_s(symInfo, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL);_tcscpy_s(srcInfo, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL);//pos = m_AllocatedMemoryList.GetStartPosition();//while(pos != m_AllocatedMemoryList.end()){numLeaks++;_stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Memory Leak(%d)------------------->\n"), numLeaks);AfxTrace(buf);#ifdef UNICODEWideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL );myfile << dest;#elsemyfile << buf;#endif//m_AllocatedMemoryList.GetNextAssoc(pos, (LPVOID &) addr, (AllocBlockInfo&) ainfo);if (ainfo.fileName[0] != NULL){_stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Memory Leak <0x%p> bytes(%d) occurance(%d) %s(%d)\n"), ainfo.address, ainfo.size, ainfo.occurance, ainfo.fileName, ainfo.lineNumber);}else{_stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Memory Leak <0x%p> bytes(%d) occurance(%d)\n"), ainfo.address, ainfo.size, ainfo.occurance);}//AfxTrace(buf);#ifdef UNICODEWideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL );myfile << dest;#elsemyfile << buf;#endif//p = &ainfo.traceinfo[0];while(p[0].addrPC.Offset){symFunctionInfoFromAddresses( p[0].addrPC.Offset, p[0].addrFrame.Offset, symInfo, MLD_MAX_NAME_LENGTH);symSourceInfoFromAddress(     p[0].addrPC.Offset, srcInfo );_stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("%s->%s()\n"), srcInfo, symInfo);AfxTrace(_T("%s->%s()\n"), srcInfo, symInfo);#ifdef UNICODEWideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL );myfile << dest;#elsemyfile << buf;#endifp++;}totalSize += ainfo.size;}_stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("\n-----------------------------------------------------------\n"));AfxTrace(buf);#ifdef UNICODEWideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL );myfile << dest;#elsemyfile << buf;#endifif(!totalSize) {_stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("No Memory Leaks Detected for %d Allocations\n\n"), memoccurance);AfxTrace(buf);#ifdef UNICODEWideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL );myfile << dest;#elsemyfile << buf;#endif}else{_stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Total %d Memory Leaks: %d bytes Total Alocations %d\n\n"), numLeaks, totalSize, memoccurance);}AfxTrace(buf);#ifdef UNICODEWideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL );const TCHAR *umb = _T("Unicode");myfile << dest;#elsemyfile << buf;const TCHAR *umb = _T("Multibyte");#endif#ifdef _WIN64const TCHAR *w64 = _T("64 bit");#elseconst TCHAR *w64 = _T("32 bit");#endif#ifdef NDEBUGconst TCHAR *dbg = _T("release build.");#elseconst TCHAR *dbg = _T("debug build.");#endif_stprintf_s(TempDir, MAX_PATH, _T("%s %s %s\n"), umb, w64, dbg);#ifdef UNICODEWideCharToMultiByte( CP_ACP, 0, TempDir, -1, dest, 1024, NULL, NULL );myfile << dest;AfxTrace(TempDir);#elsemyfile << TempDir;AfxTrace(TempDir);#endifmyfile.close();}void CMemLeakDetect::Init(){m_func = (CaptureStackBackTraceType)(GetProcAddress( m_k32 = LoadLibrary(_T("kernel32.dll")), "RtlCaptureStackBackTrace"));m_dwsymBufSize= (MLD_MAX_NAME_LENGTH + sizeof(PIMAGEHLP_SYMBOL));m_hProcess= GetCurrentProcess();m_pSymbol= (IMAGE_SYM)GlobalAlloc( GMEM_FIXED, m_dwsymBufSize);m_AllocatedMemoryList.InitHashTable(10211, TRUE);initSymInfo( NULL );isLocked= false;g_pMemTrace= this;pfnOldCrtAllocHook= _CrtSetAllocHook( catchMemoryAllocHook ); }void CMemLeakDetect::End(){isLocked= true;_CrtSetAllocHook(pfnOldCrtAllocHook);dumpMemoryTrace();cleanupMemoryTrace();cleanupSymInfo();GlobalFree(m_pSymbol);g_pMemTrace= NULL;FreeLibrary(m_k32);}CMemLeakDetect::CMemLeakDetect(){Init();}CMemLeakDetect::~CMemLeakDetect(){End();}// PRIVATE STUFFvoid CMemLeakDetect::symbolPaths( TCHAR* lpszSymbolPath){TCHAR lpszPath[MLD_MAX_NAME_LENGTH];   // Creating the default path where the dgbhelp.dll is located   // ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"_tcscpy_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, _T(".;..\\;..\\..\\"));// environment variable _NT_SYMBOL_PATHif ( GetEnvironmentVariable(_T("_NT_SYMBOL_PATH"), lpszPath, MLD_MAX_NAME_LENGTH )){_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, _T(";"));_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, lpszPath );}// environment variable _NT_ALTERNATE_SYMBOL_PATHif ( GetEnvironmentVariable( _T("_NT_ALTERNATE_SYMBOL_PATH"), lpszPath, MLD_MAX_NAME_LENGTH )){_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, _T(";"));_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, lpszPath );}// environment variable SYSTEMROOTif ( GetEnvironmentVariable( _T("SYSTEMROOT"), lpszPath, MLD_MAX_NAME_LENGTH ) ){    _tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, _T(";"));_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, lpszPath);_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, _T(";"));// SYSTEMROOT\System32_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, lpszPath );_tcscat_s( lpszSymbolPath, MLD_MAX_NAME_LENGTH, _T("\\System32"));}}BOOL CMemLeakDetect::cleanupSymInfo(){return SymCleanup( GetCurrentProcess() );}// Initializes the symbol filesBOOL CMemLeakDetect::initSymInfo( TCHAR* lpszUserSymbolPath ){TCHAR   lpszSymbolPath[MLD_MAX_NAME_LENGTH];    DWORD   symOptions = SymGetOptions();symOptions |= SYMOPT_LOAD_LINES; symOptions &= ~SYMOPT_UNDNAME;SymSetOptions( symOptions );    // Get the search path for the symbol filessymbolPaths( lpszSymbolPath);//if (lpszUserSymbolPath){_tcscat_s(lpszSymbolPath, MLD_MAX_NAME_LENGTH, _T(";"));_tcscat_s(lpszSymbolPath, MLD_MAX_NAME_LENGTH, lpszUserSymbolPath);}#ifdef UNICODEint len = (int)_tcslen(lpszSymbolPath) + 1 ;char dest[1024] ;WideCharToMultiByte( CP_ACP, 0, lpszSymbolPath, -1, dest, len, NULL, NULL );BOOL bret = SymInitialize( GetCurrentProcess(), dest, TRUE);#elseBOOL bret = SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE) ;#endifreturn bret;}/*void CMemLeakDetect::symStackTrace(STACKFRAMEENTRY* pStacktrace ){STACKFRAME     callStack;BOOL           bResult;CONTEXT        context;HANDLE   hThread  = GetCurrentThread();// get the contextmemset( &context, NULL, sizeof(context) );context.ContextFlags = CONTEXT_FULL;if ( !GetThreadContext( hThread, &context ) ){    //   AfxTrace("Call stack info(thread=0x%X) failed.\n", hThread );   return;}//initialize the call stackmemset( &callStack, NULL, sizeof(callStack) );callStack.AddrPC.Offset    = context.Eip;callStack.AddrStack.Offset = context.Esp;callStack.AddrFrame.Offset = context.Ebp;callStack.AddrPC.Mode      = AddrModeFlat;callStack.AddrStack.Mode   = AddrModeFlat;callStack.AddrFrame.Mode   = AddrModeFlat;//for( DWORD index = 0; index < MLD_MAX_TRACEINFO; index++ ) {bResult = StackWalk(IMAGE_FILE_MACHINE_I386,m_hProcess,hThread,&callStack,NULL, NULL,SymFunctionTableAccess,SymGetModuleBase,NULL);//if ( index == 0 ) //  continue;if( !bResult || callStack.AddrFrame.Offset == 0 ) break;//pStacktrace[0].addrPC = callStack.AddrPC;pStacktrace[0].addrFrame = callStack.AddrFrame;pStacktrace++;}//clear the last entrymemset(pStacktrace, NULL, sizeof(STACKFRAMEENTRY));}*///// This code is still under investigation// I have to test this code and make sure it is compatible// with the other stack walker!//void CMemLeakDetect::symStackTrace2(STACKFRAMEENTRY* pStacktrace ){longStackIndex= 0;ADDRblock[63];memset(block,0,sizeof(block));USHORT frames = (m_func)(3,59,(void**)block,NULL);for (int i = 0; i < frames ; i++){ADDRInstructionPtr = (ADDR)block[i];pStacktrace[StackIndex].addrPC.Offset= InstructionPtr;pStacktrace[StackIndex].addrPC.Segment= NULL;pStacktrace[StackIndex].addrPC.Mode= AddrModeFlat;//StackIndex++;}pStacktrace[StackIndex].addrPC.Offset = 0;pStacktrace[StackIndex].addrPC.Segment = 0;}BOOL CMemLeakDetect::symFunctionInfoFromAddresses( ADDR fnAddress, ADDR stackAddress, TCHAR *lpszSymbol,UINT BufSizeTCHARs){ADDR             dwDisp= 0;::ZeroMemory(m_pSymbol, m_dwsymBufSize );m_pSymbol->SizeOfStruct= sizeof(IMAGEHLP_LINE64);//m_pSymbol->MaxNameLength= DWORD64 - sizeof(IMAGEHLP_SYMBOL64);    // Set the default to unknown_tcscpy_s( lpszSymbol, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL);// Get symbol info for IPif ( SymGetSymFromAddr( m_hProcess, (ADDR)fnAddress, &dwDisp, m_pSymbol ) ){#ifdef UNICODEint len = (int)strlen(m_pSymbol->Name) + 1 ;wchar_t dest[1024] ;MultiByteToWideChar(CP_ACP, 0, m_pSymbol->Name, len, dest, len );_tcscpy_s(lpszSymbol, BufSizeTCHARs, dest);#else_tcscpy_s(lpszSymbol, BufSizeTCHARs, m_pSymbol->Name);#endifreturn TRUE;}//create the symbol using the address because we have no symbol_stprintf_s(lpszSymbol, BufSizeTCHARs, _T("0x%08X"), fnAddress);return FALSE;}BOOL CMemLeakDetect::symSourceInfoFromAddress(ADDR address, TCHAR* lpszSourceInfo){BOOL           ret = FALSE;IMAGE_LN  lineInfo;DWORD          dwDisp;TCHAR          lpModuleInfo[MLD_MAX_NAME_LENGTH] = MLD_TRACEINFO_EMPTY;_tcscpy_s( lpszSourceInfo, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL);memset( &lineInfo, NULL, sizeof( IMAGEHLP_LINE ) );lineInfo.SizeOfStruct = sizeof( IMAGEHLP_LINE );if ( SymGetLineFromAddr( m_hProcess, address, &dwDisp, &lineInfo ) ){   // Using the "sourcefile(linenumber)" format#ifdef UNICODEwchar_t dest[1024] ;int len = (int)strlen((char *)lineInfo.FileName) + 1 ;MultiByteToWideChar(CP_ACP, 0, (char *)lineInfo.FileName, len, dest, len) ;_stprintf_s(lpszSourceInfo, MLD_MAX_NAME_LENGTH, _T("%s(%d): 0x%08X"), dest, lineInfo.LineNumber, address );//<--- Size of the char thing.#else_stprintf_s(lpszSourceInfo, MLD_MAX_NAME_LENGTH, _T("%s(%d): 0x%08X"), lineInfo.FileName, lineInfo.LineNumber, address );//<--- Size of the char thing.#endifret = TRUE;}else{        // Using the "modulename!address" format  symModuleNameFromAddress( address, lpModuleInfo );if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0')){// Using the "address" format_stprintf_s(lpszSourceInfo,MLD_MAX_NAME_LENGTH,  _T("0x%p"), lpModuleInfo, address );// Tim ???}else{_stprintf_s(lpszSourceInfo, MLD_MAX_NAME_LENGTH, _T("%sdll! 0x%08X"), lpModuleInfo, address );}ret = FALSE;}//return ret;}BOOL CMemLeakDetect::symModuleNameFromAddress( ADDR address, TCHAR* lpszModule ){BOOL              ret = FALSE;IMAGEHLP_MODULE   moduleInfo;::ZeroMemory( &moduleInfo, sizeof(IMAGEHLP_MODULE) );moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE);if ( SymGetModuleInfo( m_hProcess, (ADDR)address, &moduleInfo ) ){// Note. IMAGEHLP_MODULE::ModuleName seems to be hardcoded as 32 char/wchar_t (VS2008).#ifdef UNICODEint len = (int)_tcslen(lpszModule) + 1 ;char dest[1024] ;WideCharToMultiByte( CP_ACP, 0, lpszModule, -1, dest, len, NULL, NULL );strcpy_s(moduleInfo.ModuleName, 32, dest);// bloody ANSI!#elsestrcpy_s(moduleInfo.ModuleName, 32, lpszModule);#endifret = TRUE;}else{_tcscpy_s( lpszModule, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL);}return ret;}static void DeleteOldTempFiles(const TCHAR dir[], const TCHAR type[], int days){union tu{FILETIME fileTime;ULARGE_INTEGER ul;};// Seems simplest way to do the Win32 time manipulation.WIN32_FIND_DATA FindFileData;HANDLE hFind = INVALID_HANDLE_VALUE;TCHAR curdir[MAX_PATH];GetCurrentDirectory(MAX_PATH, curdir);// Ignoring failure!SetCurrentDirectory(dir);hFind = FindFirstFile(type, &FindFileData);if (hFind != INVALID_HANDLE_VALUE){SYSTEMTIME st;tu ft;GetSystemTime(&st);SystemTimeToFileTime(&st, &ft.fileTime);while (FindNextFile(hFind, &FindFileData) != 0){if (FILE_ATTRIBUTE_DIRECTORY != FindFileData.dwFileAttributes){tu t;t.fileTime = FindFileData.ftCreationTime;_int64 delta = (ft.ul.QuadPart - t.ul.QuadPart) / 10000000;// Seconds.int ddays = (int)(delta /= (24 * 3600));//_tprintf (TEXT("Next file name is: %s delta days %d\n"), FindFileData.cFileName, ddays);if (ddays >= days){//_tprintf (TEXT("Next file to delete is: %s delta days %d\n"), FindFileData.cFileName, ddays);DeleteFile(FindFileData.cFileName);}//else//{//_tprintf (TEXT("Skipping: %s delta days %d\n"), FindFileData.cFileName, ddays);//}}}FindClose(hFind);}SetCurrentDirectory(curdir);}#endif


  使用的方法也可第一种一样了.. 就是定义一个全局对象..

 

原创粉丝点击