VLD检测内存泄露原理及源码分析

包含vld.h的时候,使用pragma comment链接vldddlib(采用预编译指令,根据不同的工程链接不同的lib)

 

通过全局变量

VisualLeakDetector visualleakdetector;

的构造和析构来启动和终止内存跟踪

 

构造函数中使用_CrtSetAllocHook函数设置钩子函数捕获_HOOK_ALLOC、_HOOK_FREE、_HOOK_REALLOC等事件。

设置钩子函数

m_poldhook = _CrtSetAllocHook(allochook);

 

nt VisualLeakDetector::allochook (int type, void *pdata, size_t size, int use, long request, const unsigned char *file, int line)

...

 switch (type) {

    case _HOOK_ALLOC:

        visualleakdetector.hookmalloc(request);

        break;

 

    case _HOOK_FREE:

        visualleakdetector.hookfree(pdata);

        break;

 

    case _HOOK_REALLOC:

        visualleakdetector.hookrealloc(pdata, request);

        break;

...

 

释放内容时,从堆栈中清除对应的分配请求

void VisualLeakDetector::hookfree (const void *pdata)

{

    long request = pHdr(pdata)->lRequest;

 

    m_mallocmap->erase(request);

}

 

保存分配请求在堆栈中

void VisualLeakDetector::hookmalloc (long request)

{

    CallStack *callstack;

 

    if (!enabled()) {

        // Memory leak detection is disabled. Don't track allocations.

        return;

    }

 

    callstack = m_mallocmap->insert(request);

    getstacktrace(callstack);

}

 

void VisualLeakDetector::hookrealloc (const void *pdata, long request)

{

    // Do a free, then do a malloc.

    hookfree(pdata);

    hookmalloc(request);

}

 

析构时,堆栈中剩余的内容就是泄露的内存

报告内存泄露情况时,使用dbghelp.dll中的如下函数获取分配内存时的函数调用堆栈,函数名称,所在源码文件以及行号等内容

StackWalk64;

SymCleanup;

SymFromAddr;

SymFunctionTableAccess64;

SymGetModuleBase64;

SymGetLineFromAddr64;

SymInitialize;

SymSetOptions;

这些函数的含义及使用情况参加MSDN

你可能感兴趣的:(C&C++,Windows开发)