2

umdh.exe を使用してメモリ リークをトラブルシューティングする方法を学ぼうとしています。それを行うために、サンプルアプリを作成しました:

void MemoryLeakTest(int argc, _TCHAR* argv[]);

int _tmain(int argc, _TCHAR* argv[])
{
    MemoryLeakTest(argc, argv);
    return 0;
}

void MemoryLeakTest(int argc, _TCHAR* argv[])
{
    if (argc != 3)
    {
        wcout << "HelloWorld.exe <number of allocations> <number of bytes>" << endl;
        getchar();
        return;
    }

    int numAllocations = _wtoi(argv[1]);
    int numBytes = _wtoi(argv[2]);

    wcout << "Num allocations: " << numAllocations << ", num bytes: " << numBytes << endl;
    wcout << "Press any key to start..." << endl; 
    getchar();

    for (int i = 0; i < numAllocations; ++i)
    {
        void* unusedMemory = new byte[numBytes];

        if ((i % (numAllocations / 100)) == 0)
        {
            wcout << i << endl;
            Sleep(100);
        }
    }

    wcout << "Press any key to finish..." << endl;
    getchar();
}

コンパイル済み (リリース)、構成済みの umdh.exe:

  1. set _NT_SYMBOL_PATH= http://msdl.microsoft.com/symbols/download;C :\TestProjects\HelloWorld\x64\Release;
  2. gflags.exe /i HelloWorld.exe +ust

次に、実験を行いました:

  1. HelloWorld.exe 10000 1000
  2. 止まるまで待った @ 最初の getchar
  3. umdh.exe -pn:helloworld.exe -f:c:\first.log
  4. 実行を継続し、停止するまで待機 @ second getchar
  5. umdh.exe -pn:helloworld.exe -f:c:\second.log

私が気付いたのは、100回の割り当てであろうと1000回の割り当てであろうと、呼び出すパラメータに関係なく、first.logとsecond.logが非常に似ていることです(実験が異なるため)。

  1. umdh.exe -dc:\first.log c:\second.log -f:c:\result.log

そして、予想される1000ではなく、 17 個の allocsを持つ唯一のスタックを取得します。

+   17000 (  17000 -      0)     17 allocs  BackTraceB5023D4D
+      17 (     17 -      0)    BackTraceB5023D4D   allocations

ntdll!memset+165B9
MSVCR120!malloc+5B
MSVCR120!operator new+1F
HelloWorld!MemoryLeakTest+108 (c:\my\main\private\testproject\debugit\helloworld\helloworld.cpp, 40)
HelloWorld!wmain+9 (c:\my\main\private\testproject\debugit\helloworld\helloworld.cpp, 16)
HelloWorld!__tmainCRTStartup+10F (f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c, 623)
KERNEL32!BaseThreadInitThunk+D
ntdll!RtlUserThreadStart+1D

更新: TaskProcess は、プライベート バイトとコミット サイズの両方が期待値で増加することを示しています。

UPDATED2: DebugDiag は、10000 の割り当てと正しい場所を指しているいくつかのサンプリングされたコール スタックでリークを正しく示します。

私が間違っていることは何か分かりますか?

ありがとうございました!

4

0 に答える 0