← На главную

Zsh 5.9.2 исправил 10-летний баг: SIGINT усекал историю команд

15.08.2026 21:39 · hackernews

Zsh терял команды из истории. Наутро в ~/.zsh_history оставались только старые записи, хотя вчерашние точно были. Никакой видимой порчи файла не наблюдалось. Автор сначала восстанавливал историю из бэкапа, но баг повторялся.

Через inotify он увидел, что Zsh читает старый файл, создаёт .zsh_history.new и переименовывает его поверх старого. fatrace показал PID процесса, но не объёмы данных. strace автор приберёг до репро, а bpftrace-скрипт на системные вызовы zsh дал главное: иногда Zsh читает заметно меньше байт и записывает усечённый файл.

Дальше — патч. Автор модифицировал Zsh 5.9.1 так, чтобы после записи .zsh_history.new с менее чем 50000 строк процесс нарочно падал. systemd-coredump собрал core dump. В gdb: lines_written = 45546, errflag = 2, lasthist.interrupted = 1. readhistfile прервался сигналом, но savehistfile всё равно записал неполные данные.

Причина: при выходе zexit вызывает savehistfile для компактизации истории; тот вызывает readhistfile. Если в этот момент приходит SIGINT (типичная привычка автора — гасить сессии через Ctrl+D и Ctrl+C), чтение обрывается, а запись этого не проверяет и перезаписывает файл обрезанным содержимым. lseek в логах — следствие glibc и POSIX-правила для fclose(), к багу отношения не имеет. Баг оставался в Zsh около 10 лет. Отчёт в zsh-workers разобрал Bart Schaefer, фикс не успели включить в 5.9.1, но он есть в Zsh 5.9.2 от 12 июля 2026.

В приложениях — два бонуса. Emacs TRAMP по умолчанию экспортирует HISTFILE; если потом запустить bash с его HISTFILESIZE, можно нечаянно обрезать ~/.zsh_history до 64000 строк. Автор советует разэкспортировать HISTFILE. И проверка: смогут ли современные LLM найти этот баг. По одному описанию симптома и bpftrace-логам с задачей справились OpenAI GPT-5.6-sol и Anthropic Claude Opus 5. С подсказкой про Ctrl+C/Ctrl+D проходят больше моделей. Среди open weight лучшая — Kimi K3; GLM 5.2 справляется с подсказкой. Частая ошибка моделей: они выбирают неверную теорию и застревают на её проверке.

Читать оригинал →