显示Windows上最大内存泄漏的位置

时间:2016-02-12 05:53:23

标签: windows visual-studio debugging memory-leaks heap

我的程序漏洞很大。我将调试堆放在我的stdafx.h

中使用调试堆
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

然后我通过在退出之前放置此代码来捕获文本文件中的所有泄漏:

HANDLE hLogFile;
hLogFile = CreateFile( "T:\\MyProject\\heap.txt", GENERIC_WRITE, 
                       FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 
                       FILE_ATTRIBUTE_NORMAL, NULL);
 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
 _CrtSetReportFile(_CRT_WARN, hLogFile);

_CrtDumpMemoryLeaks();

exit( EXIT_SUCCESS );

然而,即使这样,数据也会因泄漏泄漏,这是一个太低级别的信息。

1 个答案:

答案 0 :(得分:0)

进入_CrtDumpMemoryLeaks(),代码实际上很容易理解。我编写了自己的函数来汇总数据,报告每行代码泄漏的字节数,并按泄漏大小排序。

但是,为了工作,它需要dbgheap.c中的静态变量。我试图制作一个版本的dbgheap.c没有这些作为静态符号,并试图用它制作一个迷你DLL(但它抱怨我找不到任何地方的遗漏符号MSFT代码,_heap_regions)。相反,我已经解决的问题是将此代码放在调用_CrtDumpMemoryLeaks()上面的代码之前:

// Put a breakpoint here; step INTO the malloc, then in variable watch
// window evaluate: _CrtDumpMemoryLeakSummary( _pFirstBlock );
void* pvAccess = malloc(1);

反过来,这是_CrtDumpMemoryLeakSummary函数的代码:

    #define _CRTBLD
    #include "C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\dbgint.h"

    typedef struct {
        const char* pszFileName;
        int         iLine;
        int         iTotal;
    } Location_T;

    #define MAX_SUMMARY 5000
    static Location_T aloc[ MAX_SUMMARY ];



    static int CompareFn( const void* pv1, const void* pv2 ) {
      Location_T* ploc1 = (Location_T*) pv1;
      Location_T* ploc2 = (Location_T*) pv2;

      if ( ploc1->iTotal > ploc2->iTotal )
          return -1;
      if ( ploc1->iTotal < ploc2->iTotal )
          return 1;
      return 0;
    }



    void _CrtDumpMemoryLeakSummary( _CrtMemBlockHeader* pHead )
    {
          int iLocUsed = 0, iUnbucketed = 0, i;

          for ( /*pHead = _pFirstBlock */;
                pHead != NULL && /* pHead != _pLastBlock && */ iLocUsed < MAX_SUMMARY;
                pHead = pHead->pBlockHeaderNext ) {

               const char* pszFileName = pHead->szFileName ? pHead->szFileName : "<UNKNOWN>";

               // Linear search is theoretically horribly slow but saves trouble of
               // avoiding heap use while measuring heap use.
               int i;
               for ( i = 0; i < iLocUsed; i++ ) {

                   // To speed search, compare line number (fast) before strcmp() (slow).
                   // If szFileName were guaranteed to be __LINE__ then we could take advantage
                   // of __LINE__ always having the same address for any given file, and just
                   // compare pointers rather than using strcmp().  However, szFileName could
                   // be something else.

                   if ( pHead->nLine == aloc[i].iLine &&
                        strcmp( pszFileName, aloc[i].pszFileName ) == 0 ) {
                       aloc[i].iTotal += pHead->nDataSize;
                       break;
                   }
               }

               if ( i == iLocUsed ) {
                   aloc[i].pszFileName = pszFileName;
                   aloc[i].iLine       = pHead->nLine;
                   aloc[i].iTotal      = pHead->nDataSize;
                   iLocUsed++;
               }             
          }

          if ( iLocUsed == MAX_SUMMARY )
              _RPT0( _CRT_WARN, "\n\n\nARNING: RAN OUT OF BUCKETS! DATA INCOMPLETE!!!\n\n\n" );

          qsort( aloc, iLocUsed, sizeof( Location_T ), CompareFn );

          _RPT0(_CRT_WARN, "SUMMARY OF LEAKS\n" );
          _RPT0(_CRT_WARN, "\n" );
          _RPT0(_CRT_WARN, "bytes leaked  code location\n" );
          _RPT0(_CRT_WARN, "------------  -------------\n" );

          for ( i = 0; i < iLocUsed; i++ )
              _RPT3(_CRT_WARN, "%12d  %s:%d\n", aloc[i].iTotal, aloc[i].pszFileName, aloc[i].iLine );
    }

它产生如下输出:

SUMMARY OF LEAKS

bytes leaked  code location
------------  -------------
      912997  <UNKNOWN>:0
      377800  ..\MyProject\foo.h:205
      358400  ..\MyProject\A.cpp:959
      333672  ..\MyProject\B.cpp:359
        8192  f:\dd\vctools\crt_bld\self_x86\crt\src\_getbuf.c:58
        6144  ..\MyProject\Interpreter.cpp:196
        4608  ..\MyProject\Interpreter.cpp:254
        3634  f:\dd\vctools\crt_bld\self_x86\crt\src\stdenvp.c:126
        2960  ..\MyProject\C.cpp:947
        2089  ..\MyProject\D.cpp:1031
        2048  f:\dd\vctools\crt_bld\self_x86\crt\src\ioinit.c:136
        2048  f:\dd\vctools\crt_bld\self_x86\crt\src\_file.c:133