设为首页 加入收藏

TOP

【Visual Leak Detector】核心源码剖析(VLD 1.0)(一)
2023-07-23 13:31:56 】 浏览:164
Tags:Visual Leak Detector VLD 1.0

说明

使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇对 VLD 1.0 源码做内存泄漏检测的思路进行剖析。同系列文章目录可见 《内存泄漏检测工具》目录


1. 源码获取

version 1.0 及之前版本都使用旧的检测思路,可以在网站 CodeProject-Visual-Leak-Detector 中下载 version 1.0 的源码(国内网络资源:百度网盘-vld-1.0 源码包),同时在该网站中可以看到库作者 Dan Moulding 对旧检测原理的介绍。这个网站中有下图这段文字,但经过我一番查找,还是未找到 Dan Moulding 对后续新检测原理的介绍文章,本篇文章主要对 version 1.0 的源码进行剖析。

Oh Shit!-图片走丢了-打个广告-欢迎来博客园关注“木三百川”

version 1.0 的源码算上注释一共不到 3000 行,而且代码注释写得很详细,推荐有兴趣的仔细阅读源码。以下资料可能对理解其检测原理有帮助:

2. 源码文件概览

version 1.0 源码包中一共有 11 个文件,目录结构如下:

vld-10-src
    CHANGES.txt
    COPYING.txt
    README.html
    vld.cpp
    vld.dsp
    vld.h
    vldapi.cpp
    vldapi.h
    vldint.h
    vldutil.cpp
    vldutil.h

Oh Shit!-图片走丢了-打个广告-欢迎来博客园关注“木三百川”

其中 3.cpp 文件,4.h 文件,2.txt 文件,1.dsp 文件,1.html 文件,各文件用途简述如下:

  • 文件 README.html 为网页版的帮助文档,里面介绍了 VLD 的功能、使用方法、配置选项、编译方法、功能限制等。从这个帮助文档中可以得知:这个版本的 VLD 只能检测由 newmalloc 导致的内存泄漏,无法检测 COM 泄漏、进程外的泄漏、与 CRT 堆无关的泄漏;当需要检测多个 DLL 库时,则要在加载的第一个模块中包含 vld.h 头文件(若第一个加载的模块是个某个 DLL ,则在该 DLL 的主源文件中包含 vld.h,若第一个加载的是主 exe,则在 main 函数所在文件中包含 vld.h)。

  • 文件 CHANGES.txt 为版本迭代日志,记录了各版本的更新概要;

  • 文件 COPYING.txtLGPL 2.1 开源协议;

  • 文件 vld.dspVisual C++ 的项目文件,全称 Microsoft Developer Studio Project File

  • 文件 vldapi.h 为使用 VLD 库时需包含的头文件之一,里面声明了两个接口:VLDEnable()VLDDisable()

  • 文件 vldapi.cpp 里面是接口 VLDEnable()VLDDisable() 的函数定义;

  • 文件 vldint.h 里面定义了 dbghelp.dll 中一些函数的别名,并声明了 VisualLeakDetector 类;

  • 文件 vldutil.h 里面定义了一些 VLD 内部使用的宏,重载了内部的 new/delete 运算符,并声明了 CallStack 类与 BlockMap 类,这两个类是 VLD 自定义的数据结构,用来存储泄漏信息,CallStack 类似于 STL vectorBlockMap 类似于 STL map

  • 文件 vldutil.cppCallStackBlockMap 的类方法实现;

  • 文件 vld.h 为使用 VLD 库时需包含的头文件之一,里面是一些配置选项的宏定义,用户可使用这些宏来定制 VLD 的功能。特别地,这个文件里有以下一行代码,用来强制引用 VLD 库中的全局对象 visualleakdetector,使其链接到当前程序(资料参考 MSDN-pragma-commentMSDN-Linker-optionsMSDN-/INCLUDE)。

    // Force a symbolic reference to the global VisualLeakDetector class object from
    // the library. This enusres that the object is linked with the program, even
    // though nobody directly references it outside of the library.
    #pragma comment(linker, "/include:?visualleakdetector@@3VVisualLeakDetector@@A")
    
  • 文件 vld.cppVisualLeakDetector 的类方法实现,主要功能的代码都在这个文件里;

3. 源码剖析

3.1 注册自定义 AllocHook 函数

使用 #pragma init_seg (compiler) 指令构造一个全局对象 visualleakdetector,来确保这个对象的构造函数最先被调用(详见 vld.cpp 第 49~55 行)。

// The one and only VisualLeakDetector object instance. This is placed in the
// "compiler" initialization area, so that it gets constructed during C runtime
// initialization and before any user global objects are constructed. Also,
// disable the warning about us using the "compiler" initialization area.
#pragma warning (disable:4074)
#pragma init_seg (compiler)
VisualLeakDetector visualleakdetector;

在全局对象 visualleakdetector 的构造函数中调用 _CrtSetAllocHook 接口注册自定义 AllocHook 函数,使程序能捕捉之后的内存操作(内存分配/内存释放)事件(详见 vld.cpp 第 57~95 行)。

// Constructor - Dynamically links with the Debug Help Library and installs the
//   allocation hook function so that the C runtime's debug heap manager will
//   call the hook function for every heap request.
//
VisualLeakDetector::VisualLeakDetector ()
{
    ...

    if (m_tlsindex == TLS_OUT_OF_INDEXES) {
        report("ERROR: Visual Leak Detector: C
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇c++ container容器(string,vector.. 下一篇luogu_P1040 [NOIP2003 提高组] ..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目