РЕДАКТИРОВАТЬ : некоторые пояснения ниже
У меня есть служебное приложение для порождения (или перезапуска) других процессов, настройки окна консоли, его заголовка и значка и подключения стандартных дескрипторов к объектоподобные объекты (файл, именованный канал, сокет).
В случае любого сбоя это приложение должно завершиться немедленно и максимально быстро.
if ( !success )
ExitProcess( 1 );
Проблемы возникают с «окном» 10 поддержка загрузки параллельной библиотеки в ntdll.dll ".
Как и , описанные в этом ответе и в этой статье эта функция предотвращает быстрый сбой.
Программы, которые выполняются менее чем за 30 секунд, будут зависать из-за ntdll! TppWorkerThread ожидает ожидания простоя до завершения процесса.
![image](https://i.stack.imgur.com/PiPox.png)
![image](https://i.stack.imgur.com/nCf7z.png)
Даже если я установлю MaxLoaderThreads в реестре, пул протекторов создается, когда я вызываю LoadLibrary .
![image: MaxLoaderThreads in Registry](https://i.stack.imgur.com/oG5Bq.png)
Мой вопрос как прекратить процесс без ожидания потоков-загрузчиков, без прямого вызова ZwCreateUserProcess и без изменения реестра на целевой машине.
Моя идея состоит в том, чтобы заменить ExitProcess , который вызывает TerminateProcess следующим образом (и, похоже, работает).
VOID WINAPI ExitProcessNow( UINT uExitCode )
{
if ( TerminateProcess( GetCurrentProcess(),
uExitCode ) )
ExitThread( uExitCode );
else
ExitProcess( uExitCode );
}
EDIT Некоторые пояснения
Предположим следующую программу:
#include <Windows.h>
#ifndef _DEBUG
#pragma comment ( linker, "/ENTRY:EntryPoint" )
#else
#define EntryPoint main
#endif
#define NUMBER_OF_WORKER_THREADS 3
DWORD __stdcall WorkerThreadProc( PVOID __unused )
{
for ( ;; )
Sleep( 1000 );
}
void EntryPoint()
{
for ( int ii = NUMBER_OF_WORKER_THREADS; ii; --ii )
CloseHandle( CreateThread( NULL, 0, WorkerThreadProc, NULL, 0, NULL ) );
Sleep( 10000 );
// For demonstration do not call ExitProcess.
// ExitProcess( 0 );
}
Начальный поток запускает трех рабочих, ждет 10 секунд и затем завершается. Рабочие бегут бесконечно. Если _DEBUG
не определено, то нет кода CRT, который вызывает ExitProcess в конце main()
, и процесс продолжает работать с тремя потоками в WorkerThreadPro c.
Я наблюдал такую ситуацию. Мой процесс и / или порожденный процесс, в котором запущены три потока с точкой входа ntdll!Tp...
.
Мой код окончательно называется ExitProcess
(после замены ExitProcess
на TerminateProcess
все заработало).
Дело в том, что в случае, когда программа должна выйти, она должна выйти немедленно, независимо от каких-либо блокировок в какой-либо библиотеке или любом потоке. Может быть, это как-то связано с параллельной загрузкой или нет, может, в моем или порожденном коде такая тупик, это не имеет значения. Программа должна завершиться, и процесс должен стать сигнальным.
Основным вариантом использования этой программы является перезапуск других программ при их выходе по любой причине, как / sbin / init , когда настроен с respawn
в / etc / inittab .