• 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,只需要包含后者(其会包含前者的)

    贴下他们的源码、

    vld_def.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);
    vld.h
    ////////////////////////////////////////////////////////////////////////////////
    //
    //  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

  • 相关阅读:
    Myeclipse下使用Maven搭建spring boot项目
    Dubbo+Zookeeper视频教程
    dubbo项目实战代码展示
    流程开发Activiti 与SpringMVC整合实例
    交换两个变量的值,不使用第三个变量的四种法方
    数据库主从一致性架构优化4种方法
    数据库读写分离(aop方式完整实现)
    在本地模拟搭建zookeeper集群环境实例
    box-sizing布局
    盒子模型
  • 原文地址:https://www.cnblogs.com/ayanmw/p/2601879.html
Copyright © 2020-2023  润新知