Git Проблема с файлом sh.exe на Windows XP, медленно?

Git имеет важное значение для моего рабочего процесса. Я запускаю MSYS Git в Windows XP на своей четырехъядерной машине с 3 ГБ оперативной памяти, и обычно это отзывчиво и zippy.

Неожиданно возникла проблема, из-за которой требуется > 30 секунд для запуска любой команды из командной строки Git Bash, включая ls или cd. Интересно, что из приглашения Bash выглядит, что ls работает довольно быстро, я могу увидеть результат из ls, но для возврата запроса потребуется ~ 30 секунд. Если я переключусь в командную строку Windows (запустив cmd из меню "Пуск" ), то соответствующие команды также будут выполняться навсегда, даже для запуска. Например, git status может занять около минуты, прежде чем что-нибудь произойдет. Иногда процессы просто не заканчиваются.

Обратите внимание, что у меня установлен "MSYS Git", а также обычный "MSYS" для таких вещей, как MinGW и make.

Я считаю, что проблема связана с sh.exe, расположенной в C:\Program Files\Git\bin. Когда я запускаю ls из приглашения Bash или когда я вызываю git из приглашения Windows, диспетчер задач показывает до четырех экземпляров процессов sh.exe, которые приходят и уходят.

Здесь я жду возвращения ls, и вы можете увидеть, что диспетчер задач имеет git.exe и четыре экземпляра sh.exe: Here I am waiting for ls to return and you can see the task manager has git.exe running and four instances of sh.exe

Если я ctrl-c в середине ls, я иногда получаю ошибки, которые включают:

sh.exe": fork: Resource temporarily unavailable
      0 [main] sh.exe" 1624 proc_subproc: Couldn't duplicate my handle<0x6FC> fo
r pid 6052, Win32 error 5
sh.exe": fork: Resource temporarily unavailable

Или для git status: Статус Git

sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable

Могу ли я исправить это, чтобы Git быстро запускался, и если да, то как?

Вещи, которые я пробовал:

  • Reboot
  • Обновите MSYS Git до последней версии и перезагрузите
  • Обновите MSYS до последней версии и перезагрузите
  • Удалите MSYS и удалите и переустановите MSYS Git самостоятельно и перезагрузите

Мне очень хотелось бы не вытереть ящик и переустановить Windows, но я буду, если не смогу это исправить. Я не могу больше кода, если мне требуется > 30 с для запуска git status или cd.

Ответ 1

Обычно, когда программа занимает 30 секунд, чтобы сделать что-то, что должно быть мгновенно, скорее всего это проблема с тайм-аутом ввода-вывода, обычно это сеть, а не скорость вашего процессора или объем оперативной памяти, который у вас есть. Вы можете задаться вопросом, как задействована сеть, но это законный вопрос (я бы не знал для вашей системы тоже).

Msysgit устанавливает специальное приглашение, которое запускает специальную функцию __git_ps1, которая показывает некоторую полезную информацию в подсказке. Вы можете увидеть это с помощью echo $PS1, для моей системы это показывает:

$ echo $PS1
\[\033]0;$MSYSTEM:\w\007 \033[32m\]\[email protected]\h \[\033[33m\w$(__git_ps1)\033[0m\] $

Эта дополнительная информация полностью необязательна, и вы можете отключить ее. Поэтому попробуйте следующее в окне Msysgit:

$ PS1='$ '
$

Это будет reset приглашение по умолчанию $, а не попытка запуска и команды внутри подсказки. Если это решает проблему с задержкой, то скорее всего это будет функция __git_ps1. Попробуйте запустить его вручную:

$ __git_ps1
 (master)

и посмотрите, сколько времени потребуется для возврата.

Вы можете исправить это, удалив строку, которая вызывает __git_ps1 из C:\Program Files\Git\etc\profile:

#Comment the lines below
#PS1='\[\033]0;$MSYSTEM:\w\007
#\033[32m\]\[email protected]\h \[\033[33m\w$(__git_ps1)\033[0m\]
#$ '

Ответ 2

Итак, мы столкнулись с этой проблемой, и я думаю, что мы, наконец, проследили ее до внедрения MSys в модель безопасности Windows. Я попытаюсь опубликовать краткий обзор проблемы:

Снимок экрана: След стека застрявшего sh.exe. Обратите внимание, когда msys-1.0.dll вызывает NetServerEnum()

Это то, что происходит, когда sh.exe заблокирован на 30 секунд. Поэтому NetServerEnum() вызывается только в msys в одном месте, security.cc:228 в get_lsa_srv_inf(), который вызывается get_logon_server() и get_logon_server_and_user_domain(), который вызывается в create_token(), который вызывается seteuid() в syscalls.cc, который вызывается setuid().

Итак, по сути, происходит то, что когда инициализируется DLL msys и пытается вызвать вызов sh.exe на вызов setuid(), msys пытается верно соблюдать модель безопасности Windows и пытается найти список доменных серверов из вашего домена/рабочая группа. К сожалению, в отличие от linux, для Windows это блокирующий вызов, который занимает 5-30 секунд для завершения/таймаута, и на самом деле это не так уж необходимо, git.

Наше решение - создать новый msys.dll с отключенной функцией безопасности, установив has_security на false в winsup.cc. bash/sh.exe, который пришел с msysgit, несовместим с нашей новой версией msys.dll, поэтому нам пришлось скомпилировать новый bash.exe с нуля, не знаю почему. Конечным результатом был sh.exe, который больше не пытается сделать эти вызовы NetServerEnum и запускает разброс по размеру.

Ответ 3

Если замедление наблюдается при запуске нескольких одновременных команд Git, это может быть связано с проблемой блокировки ядра в msysgit

Мы видели, что при некоторых условиях несколько экземпляров git.exe будут ждать одного и того же объекта ядра (внутри WaitForSingleObject()), что фактически означает, что в системе может быть запущена только одна команда Git время.

Смотрите здесь: 10 git.exe processes all waiting on a single kernel object

Используя ProcessExplorer, мы могли видеть, что все git.exe процессы застряли здесь:

ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
ntoskrnl.exe!KeWaitForMutexObject+0x19f
ntoskrnl.exe!FsRtlCancellableWaitForMultipleObjects+0x5e
ntoskrnl.exe!FsRtlCancellableWaitForSingleObject+0x27 

Это похоже на эту проблему: http://code.google.com/p/msysgit/issues/detail?id=320 в том, что она не Git, а среда выполнения псевдо-Linux (mingw), который, как представляется, содержит проблему.

Мы изменили учетную запись пользователя, используемую для запуска приложений из SYSTEM, в интерактивную учетную запись пользователя, и ожидаемый объект ядра исчез:

Здоровые git.exe процессы git.exe processes spawning happily

Поэтому замедление, которое вы видите, должно быть связано с каким-либо конфликтом объектов ядра - только тогда, когда предыдущая команда Git освободила блокировку ядра, другие команды могли бы работать.

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

Ответ 4

Хотя ответ Грега решает проблему немедленной скорости, я чувствовал, что он только маскирует проблему и не решает ее.

Я начал медленно запускать git bash и после шагов, описанных Грегом, идентифицировал __git_ps1 как виновника.

Вместо того, чтобы изменять информацию о командной строке (я нахожу ее полезной для отображения информации, которую она отображает), я нашел решение, которое сработало для меня, описанное в сообщении в блоге:

Решение замедлить git bash при входе в систему как пользователь домена

Поиск в Интернете немного, я обнаружил, что git использует дом по умолчанию, в моей учетной записи установлена ​​учетная запись сети. Этот вопрос, что gitпостоянно просматривайте этот каталог, вызывая задержку.

Чтобы исправить это, я создал локальную переменную окружения пользователя, переопределяя по умолчанию, и установите его в% USERPROFILE%, который указывает на C:.\пользователи [имя пользователя]

Это же решение было также опубликовано на SO отвечая на аналогичный вопрос.

Добавление переменной окружения, возвращенной на git, на полную скорость, и я все еще получаю информацию о командной строке.

Ответ 5

У меня были проблемы с медленным процессом поиска на компьютере под управлением Windows XP. Иногда процесс fork занимает минуты.

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

Ответ 6

Если sh зависает перечисление серверов входа в NetServerEnum, попробуйте установить переменную среды LOGONSERVER на фактический сервер входа в систему.