C/C++检测内存泄漏的工具 vld Visual Leak Detector223 的使用方法和sample示例
这类的工具有 比如 :LeakDiag leakfinder "Visual Leak Detector"
vld可以从http://vld.codeplex.com/releases/view/82311 现在最新版本,包括src源代码。
安装好以后,他会提示 要求添加 dll 到环境变量中去。
使用 vld 的方法为:在自己的代码中 添加 vld 的头文件,以及 lib 声明,其会自动去环境变量path中搜索 vld_x86.dll 或vld_x64.dll ,然后 调用其中的方法的。
头文件有俩:vld_def.h 和 vld.h,只需要包含后者(其会包含前者的)
贴下他们的源码、
1 //////////////////////////////////////////////////////////////////////////////// 2 // 3 // Visual Leak Detector - Import Library Header 4 // Copyright (c) 2005-2012 VLD Team 5 // 6 // This library is free software; you can redistribute it and/or 7 // modify it under the terms of the GNU Lesser General Public 8 // License as published by the Free Software Foundation; either 9 // version 2.1 of the License, or (at your option) any later version. 10 // 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // Lesser General Public License for more details. 15 // 16 // You should have received a copy of the GNU Lesser General Public 17 // License along with this library; if not, write to the Free Software 18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 // 20 // See COPYING.txt for the full terms of the GNU Lesser General Public License. 21 // 22 //////////////////////////////////////////////////////////////////////////////// 23 24 #pragma once 25 26 #define VLD_OPT_AGGREGATE_DUPLICATES 0x0001 // If set, aggregate duplicate leaks in the leak report. 27 #define VLD_OPT_MODULE_LIST_INCLUDE 0x0002 // If set, modules in the module list are included, all others are excluded. 28 #define VLD_OPT_REPORT_TO_DEBUGGER 0x0004 // If set, the memory leak report is sent to the debugger. 29 #define VLD_OPT_REPORT_TO_FILE 0x0008 // If set, the memory leak report is sent to a file. 30 #define VLD_OPT_SAFE_STACK_WALK 0x0010 // If set, the stack is walked using the "safe" method (StackWalk64). 31 #define VLD_OPT_SELF_TEST 0x0020 // If set, perform a self-test to verify memory leak self-checking. 32 #define VLD_OPT_SLOW_DEBUGGER_DUMP 0x0040 // If set, inserts a slight delay between sending output to the debugger. 33 #define VLD_OPT_START_DISABLED 0x0080 // If set, memory leak detection will initially disabled. 34 #define VLD_OPT_TRACE_INTERNAL_FRAMES 0x0100 // If set, include useless frames (e.g. internal to VLD) in call stacks. 35 #define VLD_OPT_UNICODE_REPORT 0x0200 // If set, the leak report will be encoded UTF-16 instead of ASCII. 36 #define VLD_OPT_VLDOFF 0x0400 // If set, VLD will be completely deactivated. It will not attach to any modules. 37 #define VLD_OPT_REPORT_TO_STDOUT 0x0800 // If set, the memory leak report is sent to stdout. 38 #define VLD_OPT_SKIP_HEAPFREE_LEAKS 0x1000 // If set, VLD skip HeapFree memory leaks. 39 #define VLD_OPT_VALIDATE_HEAPFREE 0x2000 // If set, VLD verifies and reports heap consistency for HeapFree calls. 40 #define VLD_OPT_RELEASE_CRT_RUNTIME 0x4000 // If set, VLD treat CRT runtime as release version (use only with define VLD_FORCE_ENABLE). 41 42 #define VLD_RPTHOOK_INSTALL 0 43 #define VLD_RPTHOOK_REMOVE 1 44 45 typedef int (__cdecl * VLD_REPORT_HOOK)(int reportType, wchar_t *message, int *returnValue);
//////////////////////////////////////////////////////////////////////////////// // // Visual Leak Detector - Import Library Header // Copyright (c) 2005-2012 VLD Team // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // See COPYING.txt for the full terms of the GNU Lesser General Public License. // //////////////////////////////////////////////////////////////////////////////// #pragma once #include "vld_def.h" #if defined _DEBUG || defined VLD_FORCE_ENABLE #include <windows.h> //#pragma comment(lib, "vld.lib") // Force a symbolic reference to the global VisualLeakDetector class object from // the DLL. This ensures that the DLL is loaded and linked with the program, // even if no code otherwise imports any of the DLL's exports. #pragma comment(linker, "/include:__imp_?g_vld@@3VVisualLeakDetector@@A") //////////////////////////////////////////////////////////////////////////////// // // Visual Leak Detector APIs // #ifdef __cplusplus extern "C" { #endif // __cplusplus // VLDDisable - Disables Visual Leak Detector's memory leak detection at // runtime. If memory leak detection is already disabled, then calling this // function has no effect. // // Note: In multithreaded programs, this function operates on a per-thread // basis. In other words, if you call this function from one thread, then // memory leak detection is only disabled for that thread. If memory leak // detection is enabled for other threads, then it will remain enabled for // those other threads. It was designed to work this way to insulate you, // the programmer, from having to ensure thread synchronization when calling // VLDEnable() and VLDDisable(). Without this, calling these two functions // unsynchronized could result in unpredictable and unintended behavior. // But this also means that if you want to disable memory leak detection // process-wide, then you need to call this function from every thread in // the process. // // Return Value: // // None. // __declspec(dllimport) void VLDDisable (); // VLDEnable - Enables Visual Leak Detector's memory leak detection at runtime. // If memory leak detection is already enabled, which it is by default, then // calling this function has no effect. // // Note: In multithreaded programs, this function operates on a per-thread // basis. In other words, if you call this function from one thread, then // memory leak detection is only enabled for that thread. If memory leak // detection is disabled for other threads, then it will remain disabled for // those other threads. It was designed to work this way to insulate you, // the programmer, from having to ensure thread synchronization when calling // VLDEnable() and VLDDisable(). Without this, calling these two functions // unsynchronized could result in unpredictable and unintended behavior. // But this also means that if you want to enable memory leak detection // process-wide, then you need to call this function from every thread in // the process. // // Return Value: // // None. // __declspec(dllimport) void VLDEnable (); // VLDRestore - Restore Visual Leak Detector's previous state. // // Return Value: // // None. // __declspec(dllimport) void VLDRestore (); // VLDGlobalDisable - Disables Visual Leak Detector's memory leak detection at // runtime in all threads. If memory leak detection is already disabled, // then calling this function has no effect. // // Return Value: // // None. // __declspec(dllimport) void VLDGlobalDisable (); // VLDGlobalEnable - Enables Visual Leak Detector's memory leak detection // at runtime in all threads. If memory leak detection is already enabled, // which it is by default, then calling this function has no effect. // // Return Value: // // None. // __declspec(dllimport) void VLDGlobalEnable (); // VLDReportLeaks - Report leaks up to the execution point. // // Return Value: // // None. // __declspec(dllimport) UINT VLDReportLeaks (); // VLDGetLeaksCount - Return memory leaks count to the execution point. // // Return Value: // // None. // __declspec(dllimport) UINT VLDGetLeaksCount (); // VLDMarkAllLeaksAsReported - Mark all leaks as reported. // // Return Value: // // None. // __declspec(dllimport) void VLDMarkAllLeaksAsReported (); // VLDRefreshModules - Look for recently loaded DLLs and patch them if necessary. // // Return Value: // // None. // __declspec(dllimport) void VLDRefreshModules(); // VLDEnableModule - Enable Memory leak checking on the specified module. // // module: module handle. // // Return Value: // // None. // __declspec(dllimport) void VLDEnableModule(HMODULE module); // VLDDisableModule - Disable Memory leak checking on the specified module. // // module: module handle. // // Return Value: // // None. // __declspec(dllimport) void VLDDisableModule(HMODULE module); // VLDGetOptions - Return all current options. // // Return Value: // // Mask of current options. // __declspec(dllimport) UINT VLDGetOptions(); // VLDGetReportFilename - Return current report filename. // // filename: current report filename (max characters - MAX_PATH). // // Return Value: // // None. // __declspec(dllimport) void VLDGetReportFilename(WCHAR *filename); // VLDSetOptions - Update the report options via function call rather than INI file. // // option_mask: Only the following flags are checked // VLD_OPT_AGGREGATE_DUPLICATES // VLD_OPT_MODULE_LIST_INCLUDE // VLD_OPT_SAFE_STACK_WALK // VLD_OPT_SLOW_DEBUGGER_DUMP // VLD_OPT_TRACE_INTERNAL_FRAMES // VLD_OPT_START_DISABLED // VLD_OPT_SKIP_HEAPFREE_LEAKS // VLD_OPT_VALIDATE_HEAPFREE // // maxDataDump: maximum number of user-data bytes to dump for each leaked block. // // maxTraceFrames: maximum number of frames per stack trace for each leaked block. // // Return Value: // // None. // __declspec(dllimport) void VLDSetOptions(UINT option_mask, SIZE_T maxDataDump, UINT maxTraceFrames); // VLDSetModulesList - Set list of modules included/excluded in leak detection // depending on parameter "includeModules". // // modules: list of modules to be forcefully included/excluded in leak detection. // // includeModules: include or exclude that modules. // // Return Value: // // None. // __declspec(dllimport) void VLDSetModulesList(CONST WCHAR *modules, BOOL includeModules); // VLDGetModulesList - Return current list of included/excluded modules // depending on flag VLD_OPT_TRACE_INTERNAL_FRAMES. // // modules: destination string for list of included/excluded modules (maximum length 512 characters). // // size: maximum string size. // // Return Value: // // BOOL: TRUE if include modules, otherwise FALSE. // __declspec(dllimport) BOOL VLDGetModulesList(WCHAR *modules, UINT size); // VLDSetReportOptions - Update the report options via function call rather than INI file. // // Only the following flags are checked // VLD_OPT_REPORT_TO_DEBUGGER // VLD_OPT_REPORT_TO_FILE // VLD_OPT_REPORT_TO_STDOUT // VLD_OPT_UNICODE_REPORT // // filename is optional and can be NULL. // // Return Value: // // None. // __declspec(dllimport) void VLDSetReportOptions(UINT option_mask, CONST WCHAR *filename); // VLDSetReportHook - Installs or uninstalls a client-defined reporting function by hooking it // into the C run-time debug reporting process (debug version only). // // mode: The action to take: VLD_RPTHOOK_INSTALL or VLD_RPTHOOK_REMOVE. // // pfnNewHook: Report hook to install or remove. // // Return Value: // // int: 0 if success. // __declspec(dllimport) int VLDSetReportHook(int mode, VLD_REPORT_HOOK pfnNewHook); // VLDResolveCallstacks - Performs symbol resolution for all saved extent CallStack's that have // been tracked by Visual Leak Detector. This function is necessary for applications that // dynamically load and unload modules, and through which memory leaks might be included. // If this is NOT called, stack traces may have stack frames with no symbol information. This // happens because the symbol API's cannot look up symbols for a binary / module that has been unloaded // from the process. // // Return Value: // // None. // __declspec(dllexport) void VLDResolveCallstacks(); #ifdef __cplusplus } #endif // __cplusplus #else // !_DEBUG #define VLDEnable() #define VLDDisable() #define VLDRestore() #define VLDReportLeaks() 0 #define VLDGetLeaksCount() 0 #define VLDMarkAllLeaksAsReported() #define VLDRefreshModules() #define VLDEnableModule(a) #define VLDDisableModule(b) #define VLDGetOptions() 0 #define VLDGetReportFilename(a) #define VLDSetOptions(a, b, c) #define VLDSetReportHook(a, b) #define VLDSetModulesList(a) #define VLDGetModulesList(a, b) FALSE #define VLDSetReportOptions(a, b) #endif // _DEBUG
这 vld 并没有提供sample,提供的src源代码 也只是 编译成 dll的。
于是 我自己写了一个工程vldTest(用 vs2010 建立 console的 普通 的win32 程序)
下面就是测试的代码,lib和h文件 的路径 你自己看着办就行。vld.h里面也有 这个 包括 pragma lib的,注释掉 或者 将 lib添加到 path 还是 Library_Path什么环境变量中去。
下面的代码 功能是 写一个 内存泄漏 的程序,说白了,就是分配内存,但是没有释放掉。虽然程序结束会释放掉,但是如果不结束 一直 不释放的,就是内存泄漏了。下面程序 有2个内存泄漏,但是 vld 检测是3个。对了 编写成 DEBUG模式,才会启用 vld的功能。原因 看 vld.h的条件编译。
// vldTest.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include "..\include\vld.h" #pragma comment(lib,"../lib/Win32/vld.lib") class MyTest { public: MyTest(const char *szName) { // The following is the second resulting leak m_pszName = strdup(szName); } ~MyTest() { if (m_pszName != NULL) free(m_pszName); m_pszName = NULL; } protected: char *m_pszName; }; int _tmain(int argc, _TCHAR* argv[]) { int * ptrInt; ptrInt=(int*)malloc(10); memset(ptrInt,0xed,10); printf("0x%08x\n",*ptrInt); //VLDEnable(); //VLDRestore(); //VLDGlobalEnable(); // This is the "main" leak MyTest *pTest = new MyTest("This is an example"); //VLDReportLeaks(); //VLDGetLeaksCount (); return 0; }
运行效果如图:(为了显示全部,去掉了MyTest 那句话)。
如果 加上 free(ptrInt); 就没有泄漏了。如图
除了 0xedededed 这句话 其他都是 vld 的输出。如果发布成 release,默认 不会 调用 vld了。
程序参考了
http://topic.csdn.net/t/20021216/13/1265024.html
http://www.codeproject.com/Articles/3134/Memory-Leak-and-Exception-Trace-CRT-and-COM-Leaks
------------------------------------------------------------------------------------------------
一定要专业!本博客定位于 ,C语言,C++语言,Java语言,Android开发和少量的Web开发,之前是做Web开发的,其实就是ASP维护,发现EasyASP这个好框架,对前端后端数据库 都很感觉亲切啊。. linux,总之后台开发多一点。以后也愿意学习 cocos2d-x 游戏客户端的开发。