VLD(Visual LeakDetector)内存泄露库的使用

VLD简介

    由于C/C++语言没有所谓的垃圾收集器,内存的分配和释放都需要程序员自己来控制,这会给C/C++程序员带来一定的困难。当您的程序越来越复杂时,它的内存管理也会变得越来越困难。内存泄漏、内存越界是最常见的内存问题之一。
    内存泄漏如果不是很严重的话,在短时间内对程序不会造成太大的影响,而且在进程终止的时候,所有分配的内存都会释放掉。但是对于长时间运行的程序,其破坏力是惊人的,从性能下降到内存耗尽,甚至会影响到其它程序的正常运行。
    此外,内存问题存在一个共同的特点,它本身并不会有很明显的现象,当有异常出现时就很难检查问题的原因所在,这给调试内存问题带来了很大的难度。
VLD是一款用于VisualC++的免费内存泄漏检查工具。可以在codeproject.com网站上找到,相比其它的内存泄漏哦给你根据,他在检查内存泄漏的同事,还具有如下特点:
    1)  可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在的文件及行号;
    2)  可以得到泄漏内存的完整数据;
    3)  恶意设置内存泄漏报告的级别;
    4)  它以动态库的形式提供,无需编译源代码,只需要很小的改动程序;
    5)  源代码使用GNU许可发布,并有详细的文档及其注释。
    从使用的角度讲,VLD简单易用,对于使用者自己的代码中唯一需要修改的地方是#include VLD的头文件后正常运行自己的程序就可以发现内存问题。从研究角度上讲,如果输入到VLD源代码,可以学习到堆内存分片与释放的原理、内存检查的原理机器内存操作的常用技巧等。

VLD使用

    VLD网址:http://vld.codeplex.com/
    http://www.codeproject.com/Articles/9815/Visual-Leak-Detector-Enhanced-Memory-Leak-Detectio
    下载Visual LeakDetector,当前版本2.2.3,打开Visual C++ IDE的"工具"→"选项"→"项目和解决方案"→"VC++ 目录",在"包含文件"中增加VLD的头文件路径"\include"路径,在"库文件"增加VLD库文件的"\lib\Win32"路径,此外动态库的"\bin\Win32"路径在安装时已经添加到环境变量里面了,若是未添加,则需要手动拷贝"\bin\Win32"下的文件到可执行文件所在的目录中
(拷贝的文件有dbghelp.dll/Microsoft.DTfW.DHL.manifest/vld_x86.dll/vld.ini)
接下来需要将VLD加入到自己的代码中。方法很简单,只要在包含入口函数的.cpp文件中包含vld.h就可以。如果这个cpp文件中包含了stdafx.h,则将包含vld.h的语句放在stdafx.h的包含语句之后,否则放在最前面。
    示例程序:

[cpp] view plain copy

  1. #include<vld.h>                 // 包含VLD的头文件
  2. #include<stdlib.h>
  3. #include<stdio.h>
  4. void f()
  5. {
  6. int *p = new int(0x12345678);
  7. printf("p=%08x, ", p);
  8. }
  9. int main()
  10. {
  11. f();
  12. return 0;
  13. }
    注:VLD只能在Windows下使用,在包含vld.h头文件时增加预编译选项。    注:在Release模式下,不会链接VisualLeak Detector。    注:Visual LeakDetector有一些配置项,可以设置内存泄露报告的保存地(文件、调试器),拷贝"\Visual Leak Detector"路径下的vld.ini文件到执行文件所在的目录下(在IDE运行的话,则需要拷贝到工程目录下),修改以下项:ReportFile =.\memory_leak_report.txt ReportTo = both

VLD工具原理

    下面我们来看看VLD是如何工作的。在VisualC++中内置工具CRT Debug Heap工具,在使用Debug版本分配内存时,它会在内存块中记录分配该内存的文件名和行号。当程序退出时CRT会在main函数返回时做一些清理工作,此时检查调试堆内存,如果仍然有内存没释放,则一定存在内存泄漏问题。从这些没有被释放的内存块的头中可以得到文件名和行号。这种静态的方法可以检查出内存泄漏,但是不知道泄漏究竟是怎么发生的,也不知道该内存分配语句是如何被执行到的,想要了解这些必须对内存分配过程进行动态跟踪。VLD就是这样做的,在每次内存分配的时候记录其上下文,当程序退出时对检测到的内存泄漏查找其上下文信息,并转换成报告输出到Output中。

初始化

    VLD要记录每次的内存分配,它通过Windows提供的分配钩子allocation hooks来监视调试堆内存的分配。它是一个用户自定义的回调函数,在每次从堆中分配内存之前被调用,在初始化是VLD使用_CrtSetAllocation注册这个钩子函数。全局变量在程序初始化时就初始化,如果将VLD作为一个全局变量就可以与程序一起启动,但是C/C++并没有约定全局变量初始化的顺序,如果其它全局变量的构造函数中有内存分配则可能无法检测到。因此,VLD使用C/C++提供的#pragma init_seg来减少其它全局变量在它之前进行初始化。根据#pragma init_seg的定义,全局变量初始化分为3个阶段,首先是compiler阶段,一般进行C语言运行时库的初始化;然后是lib段,一般用于第三方类库的初始化扽;最后是user段,大部分的初始化都在这个阶段进行。

记录内存分配

    一个内存分配钩子函数需要具有如下的定义:int AllocHook(int allocType, void*userData, size_t size,int blockType, long requestNumber, onst unsigned char*filename, int lineNumber);    该函数需要在VLD初始化时被注册,每次从堆中分配内存前被调用,它需要处理的事情就是记录下此时的调用堆栈和此时堆内存分配的唯一标识requestNumber。得到当前堆栈的二进制表示并不是很复杂的事情,但是因为不同的体系结构、不同的编译器、不同的操作系统所产生的堆栈内容是不一样的,要解释堆栈并得到整个函数的调用过程比较复杂。不过Windows提供了一个StackWalk64函数可以获得堆栈的内容。    VLD是常用的C/C++内存泄漏检查工具,可以在ViusalC++中使用,在Viusal Studio 2008和2010中使用需要注意两点:    1)  版本问题:VLD已经更新到2.2版本,修正了许多bug,而且在2010版本下工作良好,VisualC++ 6.0推荐使用1.0版本,1.9b版本不是很稳定不建议使用,2.2版本的下载网址为http://vld.codeplex.com.    2)  设置变化:VC++Directories设置已经变化位置,在2010中设置过程如下:View | Other Window | Property ManagerGo to "VC++ Directories" settingsSet include folder pathSet lib folder path    点OK,我们就设置好了include和lib目录。

使用问题

问题1:VLD 1.9

    在vista下使用vld的使用,总是出现错误无法正常工作,后来经过搜索,在http://www.codeproject.com/KB/applications/visualleakdetector.aspx上的评论中找到了解决的方法:    评论“Solution forrunning 1.9 beta on Visual Studio 2008 with Vista ”给出了解决方法:评论1:VLD keptcrashing when trying to use 1.9g beta on Windows Vista, visual studio 2008. Itried all the suggestions on here and nothing worked. But I finally figured itout.when you make a project in visual C++ 2008,it sets some strange advanced Linker properties that cause VLD to crash:I changedLinker->Advanced->Randomized Base Address from Enable Image Randomization(/DYNAMICBASE) to Disable Image Randomization (/DYNAMICBASE:NO)Then I changed Linker->Advanced->DataExecution Prevention from Image is compatible with DEP (/NXCOMPAT) to DefaultAnd now it works perfectlyPlease let me know if this helped you!It‘ll make me feel better for spending a whole day trying to get it working! -Nadav评论2:The base address randomization seems to benot necessary. Just disable DEP.   大致的意思是说,只需要禁用DEP即可,   在工程的“属性”->“链接器”->“高级”->数据执行保护(DEP),设为“默认”(default)或者“映像与 DEP 不兼容(/NXCOMPAT:NO)“ 即可。(修改后好像不可用)。  注:这个选项只针对Vista有效!!!

问题2:VLD 2.2.3

    在项目中使用了visual leak detector,调试时程序无法启动报错“应用程序正常启动失败(0xc0150002)”。    解决流程:    查看vs输出信息最后一条是:Theprogram ‘[3980] MobileSignalAnalyzer.exe: Native‘ has exited with code-1072365566 (0xc0150002)    在网上多方查找有:http://blog.csdn.net/evilswords/article/details/5698851http://blog.csdn.net/brook0344/article/details/6685724    这两篇有解决办法,就是把VLD中的这两个复制到执行文件夹下就正常了Microsoft.VC90.CRT.manifestMicrosoft.DTfW.DHL.manifest    产生原因:    VC2003、VC2005、VC2008及其后续版本,对底层最基本的CRT、MFC、ATL库都进行了重构,为了避免不同版本的库引起冲突,重构后的库文件一般放在C://windows/WinSxS 文件夹中,并用特定的文件夹/文件名称进行标识;    与VC6不同, VC2003、VC2005、VC2008及其后续版本,引入了manifest清单的概念,即应用程序编译后会同时生成对应的.manifest文件,并将该.manifest文件作为资源编译到dll或者exe中去。.manifest文件实际上是一个XML格式的文本文件,里面记录了dll或exe中要引用的CRT、MFC、ATL库的版本和名称。VC6编译的应用程序对CRT、MFC、ATL的dll都是直接调用,而VC2003、VC2005、VC2008编译的程序都是先查询编译到资源中的manifest中的记录,然后按照记录提供的版本和名称去搜寻对应的CRT、MFC、ATL库以及随库发布的.manifest文件,搜寻的路径包括当前目录、C://windows/WinSxS等等,如果没有找到对应的库文件,则提示“应用程序正常初始化失败”。

http://blog.csdn.net/qing666888/article/details/50504187

时间: 2024-10-11 18:03:41

VLD(Visual LeakDetector)内存泄露库的使用的相关文章

【转】VLD(Visual LeakDetector)内存泄露库的使用

转载自http://blog.csdn.net/fan_hai_ping/article/details/8023433 VLD简介 由于C/C++语言没有所谓的垃圾收集器,内存的分配和释放都需要程序员自己来控制,这会给C/C++程序员带来一定的困难.当您的程序越来越复杂时,它的内存管理也会变得越来越困难.内存泄漏.内存越界是最常见的内存问题之一. 内存泄漏如果不是很严重的话,在短时间内对程序不会造成太大的影响,而且在进程终止的时候,所有分配的内存都会释放掉.但是对于长时间运行的程序,其破坏力是

Visual Leak Detector(vld)无法显示内存泄露文件名与行号

使用VLD测有没内存泄露的时候,出现(File and line number not available): (Function name unavailable) 查看VS控制台,发现 已加载"C:/WINDOWS/system32/dbghelp.dll" 说明VS加载了WINDOWS的dll而不是最新的VLD的dbghelp.dll 解决方案: 只需把VLD 安装路径下的 dbghelp.dll拷贝到你的程序的Debug文件夹里 就轻松搞定! Visual Leak Detec

Visual C++内存泄露检测—VLD工具使用说明[转]

Visual C++内存泄露检测—VLD工具使用说明 一.        VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号: 可以得到泄露内存的完整数据: 可以设置内存泄露报告的级别:并且是开源免费的. 二.        VLD下载 http://www.codeproject.com/tools/visualleakdetector.as

Visual C++内存泄露检测—VLD工具使用说明 .

1.VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号: 可以得到泄露内存的完整数据: 可以设置内存泄露报告的级别:并且是开源免费的. 2.VLD下载 http://www.codeproject.com/tools/visualleakdetector.asp 本文后附有vld1.0的工具包,下载解包后就可使用. 3.VLD安装 方法一: 解

Visual Leak Detector 2 2 3 Visual C++内存检测工具

Visual Leak Detector是一款免费的.健全的.开源的Visual C++内存泄露检测系统.相比Visual C++自带的内存检测机制,Visual Leak Detector可以显示导致内存泄露的完整内存分配调用堆栈. 主页地址:http://vld.codeplex.com/ 旧版地址:http://www.codeproject.com/Articles/9815/Visual-Leak-Detector-Enhanced-Memory-Leak-Detectio 下载Vis

C++技术问题总结-第15篇 内存泄露有哪些方法定位,崩溃有哪些方法定位

Visual C++内存泄露检测,可采用VLD工具. VLD:Visual Leak Detector.VLD是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号:可以得到泄露内存的完整数据:可以设置内存泄露报告的级别:并且是开源免费的. 官方网址:http://vld.codeplex.com/releases/view/82311 使用步骤: 1)官网下载VLD工具包. 2)解压后得到vld.h, vlda

vld(Visual Leak Detector) 内存泄露检测工具

初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复 杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题.内存泄漏是最常见的内存问题之一.内存泄漏如果不是很严重,在短时间内对程序不会有太大的 影响,这也使得内存泄漏问题有很强的隐蔽性,不容易被发现.然而不管内存泄漏多么轻微,当程序长时间运行时,其破坏力是惊人的,从性能下降到内存耗尽,甚 至会影响到其他程序的正常运行.另外内存问题的一个共同特点是,内存问题本身

vld(Visual Leak Detector) 内存泄露检测工具,Visual C++ 2008-2015

原文: https://vld.codeplex.com/ Visual Leak Detector 是一款专用于Visual C++的内存泄漏检测工具,它免费,开源,且鲁棒性高. VLD很容易使用: 1. 安装完vld后,只要告诉Visual C++哪里去找到它的头文件和库.(下载地址:https://vld.codeplex.com) 2. 然后您只要在你的c/c++工程中加上下面这一行代码,就可以使用vld了:#include <vld.h> 您的工程在Visual Studio deb

vs2010使用vld检测内存泄露

cocos2d-x不仅可以做到跨平台运行,还可以做到跨平台编译调试(当然只是编译对应平台下的应用了).众所周知,cocos2d-x是用c++编写的,而c++中最让人头疼的莫过于指针和内存泄露的问题,在windows下,cocos2d-x支持在vs下开发,这样,平时写win32项目的开发工具就可以用在cocos2d-x开发上了,善哉!今天就介绍一个检测内存泄露的工具,Visual Leak Detector,简称 vld 1.安装 这一步很简单,官网已经在上面给了,直接download吧,跳过!