Skip to content

Git-команды могут навсегда зависнуть после timeout на Windows #26

Description

@APonkratov

Описание проблемы

На Windows вызовы Git в bsl_index.py выполняются через subprocess.run(..., capture_output=True, timeout=...). Git for Windows обычно запускается через C:\Program Files\Git\cmd\git.exe, который создаёт дочерний процесс mingw64\bin\git.exe.

При истечении timeout Python завершает только непосредственный процесс. Дочерний Git продолжает удерживать унаследованные stdout/stderr pipe-хэндлы, а subprocess.run после kill без дополнительного лимита вызывает communicate() для сбора вывода. В результате timeout формально уже истёк, но вызов может больше никогда не вернуть управление.

Проблема затрагивает все Git-пути: проверку репозитория при rlm_start, получение HEAD и delta для индекса, определение dirty-файлов и git_search.

Шаги воспроизведения

  1. Запустить на Windows процесс-обёртку с stdout=PIPE и stderr=PIPE.
  2. Из обёртки запустить дочерний процесс, наследующий эти pipe, и оставить его работающим дольше родителя.
  3. Вызвать обёртку через subprocess.run(..., capture_output=True, timeout=1).
  4. Дождаться TimeoutExpired: непосредственный процесс завершается, но дочерний сохраняет pipe открытыми, поэтому финальный сбор вывода зависает.
  5. В rlm-tools-bsl тот же сценарий может проявиться на медленной или зависшей Git-команде через rlm_start, обновление индекса либо git_search.

Ожидаемое поведение

Любой Git-timeout должен быть ограничен по wall-clock времени. На Windows необходимо best-effort завершить всё дерево процессов, затем ограниченно собрать/закрыть pipe и пере-бросить исходный subprocess.TimeoutExpired, чтобы существующие fallback-сценарии продолжили работу.

Фактическое поведение

После истечения заданного timeout вызов может зависнуть бессрочно на сборе stdout/stderr, а MCP-запрос или обновление индекса не возвращает ответ.

Логи rlm-сервера

Специфической ошибки может не быть: выполнение не доходит до обработки TimeoutExpired и остаётся заблокированным при закрытии capture pipe.

Окружение

  • rlm-tools-bsl: 1.32.1
  • Python: воспроизводится на поддерживаемых версиях, включая 3.14
  • ОС: Windows
  • Формат исходников 1С: не применимо

Дополнительный контекст

Исправление должно быть общим для всех точек запуска Git, без подмены Git executable и без новых зависимостей. Регрессия проверяется реальным Windows-процессом: родитель создаёт наследника, оба удерживают capture pipe; после timeout runner обязан вернуться за ограниченное время и завершить оба PID.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions