Сейчас на форуме: zds (+6 невидимых)

 eXeL@B —› Программирование —› There are no child processes to wait for. (0x80) - exit code 128 (0x80)
Посл.ответ Сообщение


Ранг: 95.2 (постоянный)
Активность: 0.040
Статус: Участник

Создано: 08 сентября 2012 22:11
· Личное сообщение · #1

Люди, есть проблема, решить которую не могу уже на протяжении года. Суть следующая:
Есть сервис, работающий на W2K3 сервере х32. Сервис многопоточный. Каждый поток создаваясь, запускает кучу приложений через CreateProcessA, многие из которых консольные. Читал, что в случае преждевременного завершения таких приложений происходит истощение кучи рабочего стола, которое в свою очередь как раз и приводит к ошибкам такого характера. Но вот ответа на вопрос как избежать этой ситуации я не нашел. Может есть у кого какие мысли по этому поводу. Буду очень признателен.

-----
бессмысленные манипуляции не становятся более разумными если их повторять




Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 09 сентября 2012 09:50
· Личное сообщение · #2

Увеличить размеры кучи:
HKLM\System\CurrentControlSet\Control\Session Manager\SubSystems ключ SharedSection (http://support.microsoft.com/kb/126962)
Service Pack 2 установлен ?



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 09 сентября 2012 14:25
· Личное сообщение · #3

SecurAdmin
Покажи код создания процессов и закрытия хендлов, скорее всего он у тебя "течет".




Ранг: 95.2 (постоянный)
Активность: 0.040
Статус: Участник

Создано: 10 сентября 2012 08:26 · Поправил: SecurAdmin
· Личное сообщение · #4

Код вот:
Code:
  1. function StartCmdFile(ACurrentDir: String; ACMDLine: String;
  2.   ATitle: String; ATerminateEventHandle: THandle; aTimeout: Cardinal = INFINITE; aAsync: boolean = false): LongWord;
  3. var
  4.   lCmdLine: String;
  5.   lStartupInfo: TStartupInfo;
  6.   lProcessInfo: TProcessInformation;
  7.   lExitCode: LongWord;
  8.   lHandleArr: TWOHandleArray;
  9.   lWaitResult: Cardinal;
  10.   SA: TSecurityAttributes;
  11. begin
  12.   Result:= 1;
  13.  
  14.    SA.nLength := SizeOf(SA);
  15.    SA.lpSecurityDescriptor := nil;
  16.    SA.bInheritHandle := True;
  17.  
  18.   if aTimeout = 0 then   // будем считать нулевой таймаут отсутсвим таймаута
  19.     aTimeout:= INFINITE;
  20.  
  21.   lCmdLine:= Trim(ACMDLine);
  22.  
  23.  if lCmdLine = '' then
  24.   begin
  25.     Result:= 87; // The parameter is incorrect.
  26.     Exit;
  27.   end;
  28.  
  29.   // Подготовительные операции
  30.   lExitCode := 0;
  31.   FillChar(lStartupInfo, Sizeof(TStartupInfo), #0);
  32.  
  33.   with lStartupInfo do
  34.   begin
  35.     cb := SizeOf(TStartupInfo);
  36.     lpTitle := PChar(ATitle);
  37.   end;
  38.  
  39.   // Создаем процесс
  40.   if not CreateProcess(nil, PChar(lCmdLine), @SA, @SA, TRUE, //<b>собственно, вот тут и начинаются ошибки...</b>
  41.     {CREATE_SUSPENDED and} NORMAL_PRIORITY_CLASS, nil,
  42.     PChar(ACurrentDir), lStartupInfo, lProcessInfo) then
  43.   begin
  44.     Result:= GetLastError; <b>вот здесь вылезает код ошибки 128</b>
  45.     Exit;
  46.   end
  47.   else
  48.   begin
  49.     if aAsync then
  50.       Result:= 0 //предположительно тут и есть утечка...хэндлы не закрываются...
  51.     else
  52.     begin
  53.       lHandleArr[0] := ATerminateEventHandle;
  54.       lHandleArr[1] := lProcessInfo.hProcess;
  55.       try
  56.         lWaitResult:= WaitForMultipleObjects(2, @lHandleArr, False, aTimeout);
  57.         if lWaitResult = 0 then
  58.         begin
  59.           TerminateProcess(lProcessInfo.hProcess, WAIT_TIMEOUT);
  60.           lWaitResult:= WaitForSingleObject(lProcessInfo.hProcess, aTimeout);
  61.         end;
  62.         if lWaitResult = WAIT_TIMEOUT     then
  63.         begin
  64.           TerminateProcess(lProcessInfo.hProcess, WAIT_TIMEOUT);
  65.           Result:= WAIT_TIMEOUT;
  66.           exit;
  67.         end;
  68.         GetExitCodeProcess(lProcessInfo.hProcess, lExitCode);
  69.         Result := lExitCode;
  70.       finally
  71.         CloseHandle(lProcessInfo.hThread);
  72.         CloseHandle(lProcessInfo.hProcess);
  73.       end;
  74.     end;
  75.   end;
  76. end;


-----
бессмысленные манипуляции не становятся более разумными если их повторять





Ранг: 164.6 (ветеран), 65thx
Активность: 0.120
Статус: Участник
Волшебник

Создано: 10 сентября 2012 10:30
· Личное сообщение · #5

128 - Дочерние процессы, окончания которых требуется ожидать, отсутствуют. Суть ошибки в указанном месте не совсем мне ясна. Как я понимаю закрывать хэндл основного потока не обязательно, достаточно закрыть хэндл процесса. Для TerminateProcess хэндл должен обладать правами PROCESS_TERMINATE. Если aAsync, хэндл процесса вообще не закрывается.

-----
Следуй за белым кроликом





Ранг: 95.2 (постоянный)
Активность: 0.040
Статус: Участник

Создано: 10 сентября 2012 13:13
· Личное сообщение · #6

neomant
Не спорю, просто я уже не знаю, на что думать. В каком случае и при каких обстоятельствах эта ошибка вообще возникает. Куда деваются дочки, завершение работы которых ожидает поток сервиса? Почему он теряет их? как избежать этой проблемы?
Сейчас единственной полумерой считаю увеличение размера кучи рабочего стола. Но хочется решить эту проблему на корню!

-----
бессмысленные манипуляции не становятся более разумными если их повторять




Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 10 сентября 2012 14:34 · Поправил: F_a_u_s_t
· Личное сообщение · #7

Code:
  1.   begin
  2.     if aAsync then // насколько я понял, флажек отвечает за ассинхронный вызов, а дальше что?
  3.       Result:= 0 
  4.     else
  5.     begin
  6.       lHandleArr[0] := ATerminateEventHandle;
  7.       lHandleArr[1] := lProcessInfo.hProcess;
  8.       try
  9.         lWaitResult:= WaitForMultipleObjects(2, @lHandleArr, False, aTimeout);
  10.         if lWaitResult = 0 then
  11.         begin
  12.           TerminateProcess(lProcessInfo.hProcess, WAIT_TIMEOUT);
  13.           lWaitResult:= WaitForSingleObject(lProcessInfo.hProcess, aTimeout);
  14.         end;
  15.         if lWaitResult = WAIT_TIMEOUT     then
  16.         begin
  17.           TerminateProcess(lProcessInfo.hProcess, WAIT_TIMEOUT);
  18.           Result:= WAIT_TIMEOUT;
  19.           exit; // тут что потом делаем?
  20.         end;
  21.         GetExitCodeProcess(lProcessInfo.hProcess, lExitCode);
  22.         Result := lExitCode;
  23.       finally
  24.         CloseHandle(lProcessInfo.hThread);
  25.         CloseHandle(lProcessInfo.hProcess);
  26.       end;


Почисти проект от "рабочего" кода и выложи, так проще будет.



Ранг: 65.3 (постоянный), 10thx
Активность: 0.020
Статус: Участник

Создано: 12 сентября 2012 20:36
· Личное сообщение · #8

SecurAdmin
Во-первых, не понял, что мешает закрыть хендлы в случае aAsync. Во-вторых, судя по описанию в инете ошибки 128, это не ошибка, а код завершения приложения, который должен выдавать GetExitCodeProcess(). Вы уверены, что 128 - это ответ GetLastError() после CreateProcess()?


 eXeL@B —› Программирование —› There are no child processes to wait for. (0x80) - exit code 128 (0x80)
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати