NetServerEnum создает рабочие потоки, которые не закрываются

Пытаясь решить мой ранее заданный вопрос, я обнаружил, что проблема возникает даже без моих потоков.

то, что я имею сейчас, это действительно простой однопоточный код, который вызывает - NetServerEnum(), по возвращении звонит NetApiBufferFree() и вернитесь с основного, который должен завершить процесс. в этот момент мой поток действительно заканчивается, но процесс не завершится, так как открыто 4 потока (не мной):

1 * ntdll.dll!TplsTimerSet+0x7c0 (стек находится в ntdll.dll!WaitForMultipleObjects)

(Этот открыт по вызову NetServerEnum())

3 * ndll.dll!RtValidateHeap+0x170 (стек находится в ntdll.dll!ZwWaitWorkViaWorkerFactory+0xa)

(Они открыты, когда мой код возвращается)

ОБНОВЛЕНИЕ: Если я убью поток, работающий с ntdll.dll!TplsTimerSet+0x7c0 извне (с помощью проводника процессов), до возврата main() Выход из программы изящно. Я думал, что это может быть полезно знать.

ОБНОВЛЕНИЕ 2: (дополнительная техническая информация) Я использую: MS Visual Studio 2010 Ultimate x64 (SP1Rel) в Win7 Enterprise SP1 Код на C (но компилируется при включенном переключателе C++) Подсистема: WINDOWS Компилятор: cl.exe (с использованием IDE) все остальные параметры по умолчанию.

Я использую самоизмененную точку входа (/ENTRY:"entry"), и это единственная функция в моей программе):

int entry(void)
{
SERVER_INFO_101* si;
DWORD a,b;
NET_API_STATUS c;
c = NetServerEnum ( NULL , 101 , (LPBYTE*) &si , MAX_PREFERRED_LENGTH , &b ,  &a  , SV_TYPE_WORKSTATION, NULL , 0 );

c = NetApiBufferFree (si);

Sleep(1000);

return 0;

}

все протестированные, упомянутые ранее, были сформированы в доменной сети Windows из примерно 100 единиц.

ОБНОВЛЕНИЕ 3: Эта проблема не возникает при тестировании на (не виртуальном) WinXP 32bit. (тот же двоичный файл, хотя для Win7 x64 были протестированы два двоичных файла - 32-битный по WOW и родной x64)

1 ответ

Решение

Когда вы используете пользовательскую точку входа, вы обходите библиотеку времени выполнения, что означает, что вы несете ответственность за выход из процесса. Процесс неявно завершится, если не будет запущено больше потоков, но, как вы обнаружили, операционная система может создавать потоки от вашего имени, которые вы не можете контролировать.

В вашем случае все, что вам нужно сделать, это позвонить ExitProcess явно в конце entry() функция.

int entry(void)
{
   SERVER_INFO_101* si;
   DWORD a,b;
   NET_API_STATUS c;

   c = NetServerEnum ( NULL , 101 , (LPBYTE*) &si , MAX_PREFERRED_LENGTH , &b ,  &a  , SV_TYPE_WORKSTATION, NULL , 0 );

   c = NetApiBufferFree (si);

   Sleep(1000);

   ExitProcess(0);
}

При отсутствии звонка ExitProcess и с пользовательской точкой входа поведение, которое вы видите, соответствует ожидаемому.

Другие вопросы по тегам