Windows создает события при отключении потока

Я пытаюсь добавить обнаружение утечки дескриптора в структуру модульного теста в моем коде. (Windows 7, x64 VS2010)

Я в основном вызываю GetProcessHandleCount () до и после каждого модульного теста.
Это прекрасно работает, за исключением случаев, когда потоки создаются / уничтожаются как часть теста.

Кажется, что windows иногда создает 1-3 события при отключении потока. Запуск одного и того же теста в цикле не увеличивает количество созданных событий. (например, выполнение теста 5000 раз в цикле приводит только к созданию 1-3 дополнительных событий)

Я не создаю события вручную в своем собственном коде.

Кажется, что это похоже на эту проблему:
boost :: thread вызывает маленькую утечку дескриптора события?
но я делаю ручное создание потока / завершение работы.

Я следовал этому коду:
http://blogs.technet.com/b/yongrhee/archive/2011/12/19/how-to-troubleshoot-a-handle-leak.aspx

И получил этот стек вызовов от WinDbg:

Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x0000000000000108 - OPEN
Thread ID = 0x00000000000030dc, Process ID = 0x0000000000000c90

0x000000007715173a: ntdll!NtCreateEvent+0x000000000000000a
0x0000000077133f26: ntdll!RtlpCreateCriticalSectionSem+0x0000000000000026
0x0000000077133ee3: ntdll!RtlpWaitOnCriticalSection+0x000000000000014e
0x000000007714e40b: ntdll!RtlEnterCriticalSection+0x00000000000000d1
0x0000000077146ad2: ntdll!LdrShutdownThread+0x0000000000000072
0x0000000077146978: ntdll!RtlExitUserThread+0x0000000000000038
0x0000000076ef59f5: kernel32!BaseThreadInitThunk+0x0000000000000015
0x000000007712c541: ntdll!RtlUserThreadStart+0x000000000000001d
--------------------------------------

Как видите, это событие, созданное при отключении потока.

Есть ли лучший способ сделать это обнаружение утечки ручки в модульных тестах? Мои единственные текущие варианты:

  • Забудьте пытаться сделать это ручкой обнаружения утечек
  • Раскрутите несколько фиктивных заданий, чтобы попытаться создать эти ложные события.
  • Разрешить небольшое значение допуска в утечках и запускать каждый тест 100 раз (поэтому фактических утечек будет много)
  • Получить количество дескрипторов, исключая события (сложное количество кода)

Я также попытался перейти на использование std :: thread в VS2013, но кажется, что он создает много фоновых потоков и дескрипторов при использовании. (делает разницу в счете намного хуже)

Вот автономный пример, где в 99 +% случаев (на моем компьютере) за кулисами создается событие. (счетчик ручки отличается). Помещение кода запуска / выключения в цикл означает, что он не протекает напрямую, а накапливает случайные события:

#include "stdio.h"#include <Windows.h>
#include <process.h>

#define THREADCOUNT 3
static HANDLE s_semCommand, s_semRender;

static unsigned __stdcall ExecutiveThread(void *)
{
WaitForSingleObject(s_semCommand, INFINITE);
ReleaseSemaphore(s_semRender, THREADCOUNT - 1, NULL);
return 0;
}

static unsigned __stdcall WorkerThread(void *)
{
WaitForSingleObject(s_semRender, INFINITE);
return 0;
}

int main(int argc, char* argv[])
{
DWORD oldHandleCount = 0;
GetProcessHandleCount(GetCurrentProcess(), &oldHandleCount);

s_semCommand = CreateSemaphoreA(NULL, 0, 0xFFFF, NULL);
s_semRender  = CreateSemaphoreA(NULL, 0, 0xFFFF, NULL);

// Spool threads up
HANDLE threads[THREADCOUNT];
for (int i = 0; i < THREADCOUNT; i++)
{
threads[i] = (HANDLE)_beginthreadex(NULL, 4096, (i==0) ? ExecutiveThread : WorkerThread, NULL, 0, NULL);
}

// Signal shutdown - Wait for threads and close semaphores
ReleaseSemaphore(s_semCommand, 1, NULL);
for (int i = 0; i < THREADCOUNT; i++)
{
WaitForSingleObject(threads[i], INFINITE);
CloseHandle(threads[i]);
}
CloseHandle(s_semCommand);
CloseHandle(s_semRender);

DWORD newHandleCount = 0;
GetProcessHandleCount(GetCurrentProcess(), &newHandleCount);
printf("Handle %d -> %d", oldHandleCount, newHandleCount);
return 0;
}

3

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]