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

 eXeL@B —› Программирование —› Недокументированный дедлок. Pipe и _LdrpLoaderLock
Посл.ответ Сообщение


Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 07 мая 2013 11:54 · Поправил: DenCoder
· Личное сообщение · #1

Всем доброго времени суток!

Много различных задач вставало у меня. На этот раз потребовалось вставить в огромный исходник какую-то замену консоли, т.е. чтобы вывод текста происходил не в консоль, а по какому-то каналу. Выбор пал на пайпу - проще! Набросал простенький код

Code:
  1. DWORD __stdcall ReadFromPipe(LPVOID)
  2. {
  3.          DWORD dwBytesRead, dwError = 0;
  4.          BOOL bReadSuccess;
  5.          while(true)
  6.          {
  7.                  char Buffer[READ_PIPE_BUFFER_SIZE];
  8.                  bReadSuccess = ReadFile(hReadPipe, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
  9.                  if(!bReadSuccess)
  10.                  {
  11.                         dwError = GetLastError();
  12.                         break;
  13.                  }
  14.                  else if(dwBytesRead == 0) break;
  15.          }
  16.  
  17.          return dwError;
  18. }
  19.  
  20. void main()
  21. {
  22.          BOOL bPipeCreated = CreatePipe(&hReadPipe, &hWritePipe, NULL, 0);
  23.          SetStdHandle(STD_INPUT_HANDLE, hReadPipe);
  24.          SetStdHandle(STD_OUTPUT_HANDLE, hWritePipe);
  25.          SetStdHandle(STD_ERROR_HANDLE, hWritePipe);
  26.  
  27.          CloseHandle(CreateThread(NULL, 0, ReadFromPipe, NULL, 0, NULL));
  28.  
  29.               //Работаем
  30.               //...
  31.               //...
  32. }


и... зависло, DeadLock! (WinXP SP3 со всеми обновлениями до мая 2013 года) call stack в студии 2010 почти ничего не дал, ясно было только, что зависание связано с ntdll!_LdrpLoaderLock. Пришлось опять подебажить систему... установлена злополучная функция - iphlpapi!GetAdaptersAddresses()->GetIpAddrTable(), которая подгружает netman.dll, в свою очередь которая тянет за собой ещё кучу. Не стал пока разбираться с этим, т.к. времени мало, но сообразил, что пара экспериментов избавят от мучений ))

Выкладываю 2 решения, которые могут помочь, дабы попавшие в аналогичную ситуацию быстрее его нашли. Мне лично 15минутный гугл-поиск ничего не дал, кроме --> одного поста <-- на experts-exchange.com - к сожалению, а может, и к счастью у меня ни карты, ни кредитки )

1. Вставляем HMODULE hmodNetman = LoadLibrary("netman.dll"); до создания потока с чтением из пайпы - куча dll по цепочке теперь спокойно грузится, ничего не виснет. При чём если загрузку модуля поставить после создания потока с чтением из пайпы - тот же дедлок;
2. Переносим SetStdHandle после отработки сетевых функций инициализации.

Только вот какая связь stdio с загрузкой dll?. Хотелось бы узнать ответ на этот вопрос, но нет времени глубоко потрошить винду. Может кто из присутствующих и иногда заходящих знает?

UPD. Оказалось, необходимо вынести в начало ещё загрузку провайдеров из ветки реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\NameSpace_Catalog5\Catalog_Entries, кроме mswsock.dll. И всё работает

-----
IZ.RU



 eXeL@B —› Программирование —› Недокументированный дедлок. Pipe и _LdrpLoaderLock
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


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