Где была выделена ручка? - PullRequest
3 голосов
/ 19 августа 2009

Мне интересно, можно ли использовать WinDbg для определения стека вызовов, который приводит к выделению дескриптора.

Например:

#include <windows.h>
#include <conio.h>
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Press ENTER to leak handles." << endl;

    _getch();

    cout << "Leaking handles" << endl;

    for (int i = 0; i < 100; ++i)
    {
        HANDLE h = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (h != NULL)
        {
            cout << ".";
        }
    }

    cout << "Handles leaked. Press ENTER to exit." << endl;

    _getch();

    return 0;
}

После создания этого примера и его запуска в WinDbg можно получить стек вызовов, который выделил дескрипторы, в примере над строкой:

HANDLE h = CreateEvent(NULL, FALSE, FALSE, NULL);

Я копаюсь с командой !handle, но пока никакого прогресса.

Это важно для анализа утечек. Мне известны !htrace -enable и !htrace -diff, но это другой сценарий использования (если для этого нет какого-либо способа комбинирования или другого вектора использования, предоставьте информацию).

1 Ответ

4 голосов
/ 19 августа 2009

Нашли то, что кажется решением:

  1. Включить трассировку с помощью !htrace -enable
  2. Запустить программу и дождаться утечки ручки
  3. Проверьте дескрипторы программы и пиковую для анализа с помощью !htrace <handle>
0:001> !htrace -enable
Handle tracing enabled.
Handle tracing information snapshot successfully taken.
0:001> g
0:001> !handle
...

Handle <b>7d8</b>
  Type          Event
...
111 Handles
Type            Count
Event           103
File            3
Port            1
Directory       2
WindowStation   1
KeyedEvent      1
0:001> !htrace <b>7d8</b>
--------------------------------------
Handle = 0x000007d8 - OPEN
Thread ID = 0x00000fc4, Process ID = 0x000017a8

0x0040106d: <b>TestMemHandleLeak!wmain+0x0000006d</b>
0x0040151b: TestMemHandleLeak!__tmainCRTStartup+0x0000010f
0x7c817077: kernel32!BaseProcessStart+0x00000023

--------------------------------------
Parsed 0x64 stack traces.
Dumped 0x1 stack traces.

И чтобы получить строку кода по этому адресу, я сделал:

0:001> ln <b>TestMemHandleLeak!wmain+0x0000006d</b>
f:\temp\windowsapplication3\testmemhandleleak\testmemhandleleak.cpp(22)
...