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 на фактический сервер входа в систему.