На главную

DevOps и серверы

Коды ошибок и сигналы Unix

errno, сигналы и коды выхода в одном месте — с правилом «128 плюс номер», из-за которого 137 означает нехватку памяти.

Разбор кода

Что означает число

Код выхода

Убит SIGKILL

128 + 9. В Docker и Kubernetes это почти всегда OOM-killer: контейнеру не хватило памяти.

Одно и то же число значит разное в разных местах, поэтому показаны все подходящие трактовки.

Показано 66 из 66 строк.

Коды выхода

В оболочке код последней команды лежит в $?. Всё, что больше 128, — почти всегда сигнал.

  • 0

    Успех. Единственный код, который в скриптах означает «всё хорошо».

  • 1

    Общая ошибка. Универсальный «что-то пошло не так». Большинство программ ограничивается им.

  • 2

    Неверное использование. У встроенных команд оболочки — синтаксическая ошибка или неверный ключ.

  • 126

    Команда не исполняема. Файл есть, но нет бита x, либо это каталог.

  • 127

    Команда не найдена. Нет в PATH. В контейнерах ещё и «нет sh в образе» либо не тот шебанг.

  • 128

    Неверный аргумент exit. exit с числом вне диапазона 0–255.

  • 130

    Прервано с Ctrl-C. 128 + 2 (SIGINT).

  • 137

    Убит SIGKILL. 128 + 9. В Docker и Kubernetes это почти всегда OOM-killer: контейнеру не хватило памяти.

  • 139

    Обращение к чужой памяти. 128 + 11 (SIGSEGV).

  • 141

    Обрыв канала. 128 + 13 (SIGPIPE). Типично для «cmd | head».

  • 143

    Завершён SIGTERM. 128 + 15. Штатная остановка: docker stop, systemctl stop, вытеснение пода.

  • 255

    Код вне диапазона. Часто это exit(-1): в 8 бит он превращается в 255. У ssh — ошибка самого ssh.

Сигналы

Значения приведены для Linux x86-64: на других архитектурах номера части сигналов отличаются.

  • SIGHUP (1)

    Обрыв терминала. Демоны используют его как «перечитай конфиг». Чтобы процесс пережил выход из ssh — nohup или systemd-unit.

  • SIGINT (2)

    Прерывание с клавиатуры (Ctrl-C). Программа может перехватить и завершиться аккуратно.

  • SIGQUIT (3)

    Выход с дампом (Ctrl-\). У JVM и Go печатает стеки всех потоков — удобно при зависании.

  • SIGILL (4)

    Недопустимая инструкция. Бинарник собран под другой процессор.

  • SIGABRT (6)

    Аварийное завершение. Программа сама вызвала abort(): проваленный assert, необработанное исключение в C++.

  • SIGFPE (8)

    Ошибка арифметики. Деление на ноль в целых числах.

  • SIGKILL (9)

    Немедленное убийство. Перехватить нельзя. В контейнерах чаще всего приходит от OOM-killer или как «время вышло» после SIGTERM.

  • SIGSEGV (11)

    Обращение к чужой памяти. Разыменование нулевого указателя, переполнение стека при бесконечной рекурсии.

  • SIGPIPE (13)

    Запись в закрытый канал. Именно поэтому «cmd | head» иногда завершается кодом 141.

  • SIGALRM (14)

    Сигнал таймера.

  • SIGTERM (15)

    Вежливая просьба завершиться. Сигнал по умолчанию у kill, docker stop и systemctl stop. Приложение должно закрыть соединения и выйти.

  • SIGCHLD (17)

    Дочерний процесс завершился. Игнорируется по умолчанию; необработанный — источник зомби-процессов.

  • SIGCONT (18)

    Продолжить выполнение. Пара к SIGSTOP; в оболочке это fg и bg.

  • SIGSTOP (19)

    Приостановить процесс. Перехватить нельзя, как и SIGKILL.

  • SIGTSTP (20)

    Приостановка с клавиатуры (Ctrl-Z).

  • SIGXCPU (24)

    Превышен лимит процессорного времени. ulimit -t.

  • SIGXFSZ (25)

    Превышен предел размера файла. ulimit -f.

  • SIGSYS (31)

    Недопустимый системный вызов. Часто это seccomp-фильтр в контейнере.

errno

Номер errno — это не код выхода: программа обычно превращает его в сообщение и выходит с 1.

  • EPERM (1)

    Операция не разрешена. Прав не хватает, но дело не в правах файла: обычно нужен root или соответствующая capability.

  • ENOENT (2)

    Нет такого файла или каталога. Самая частая ошибка вообще. Проверьте не только файл, но и каждый каталог пути и битые симлинки.

  • ESRCH (3)

    Нет такого процесса. PID уже завершился.

  • EINTR (4)

    Вызов прерван сигналом. Не ошибка: вызов надо повторить. В коде это забывают и получают случайные сбои.

  • EIO (5)

    Ошибка ввода-вывода. Часто физическая: диск, шлейф, сеть у сетевой ФС. Смотрите dmesg.

  • E2BIG (7)

    Слишком длинный список аргументов. Классика: rm * в каталоге с сотней тысяч файлов. Спасает find … -delete или xargs.

  • ENOEXEC (8)

    Ошибка формата исполняемого файла. Не тот формат или архитектура; иногда — отсутствующий шебанг.

  • EBADF (9)

    Неверный файловый дескриптор. Работа с уже закрытым файлом или сокетом.

  • EAGAIN / EWOULDBLOCK (11)

    Ресурс временно недоступен. Неблокирующая операция не готова — повторить позже. Иногда упирается в лимит потоков.

  • ENOMEM (12)

    Не хватает памяти. Кончилась память или сработал лимит cgroup/ulimit.

  • EACCES (13)

    Доступ запрещён. Именно права: биты доступа, владелец, ACL, SELinux. У каталога нужен ещё и бит x.

  • EBUSY (16)

    Устройство или ресурс занят. Размонтировать не даёт открытый файл — ищите через lsof.

  • EEXIST (17)

    Файл уже существует. Создание с O_EXCL или mkdir по существующему пути.

  • EXDEV (18)

    Ссылка через устройство. rename между разными файловыми системами не работает — нужно копирование.

  • ENOTDIR (20)

    Не каталог. В середине пути оказался обычный файл.

  • EISDIR (21)

    Это каталог. Попытка открыть каталог на запись как файл.

  • EINVAL (22)

    Недопустимый аргумент. Самая бессодержательная ошибка: смотрите strace, чтобы увидеть, какой именно вызов и с чем.

  • ENFILE (23)

    Переполнена системная таблица файлов. Лимит на всю систему: fs.file-max.

  • EMFILE (24)

    Слишком много открытых файлов. Лимит процесса: ulimit -n или LimitNOFILE в unit-файле. Часто это утечка дескрипторов.

  • EFBIG (27)

    Файл слишком велик. Предел файловой системы или ulimit -f.

  • ENOSPC (28)

    На устройстве не осталось места. Проверьте не только df -h, но и df -i: свободные inode кончаются раньше места.

  • EROFS (30)

    Файловая система только для чтения. Ядро перевело ФС в read-only после ошибки диска — типичный симптом умирающего накопителя.

  • EMLINK (31)

    Слишком много ссылок. Предел числа жёстких ссылок на файл.

  • EPIPE (32)

    Обрыв канала. Пишем в закрытый сокет или в конвейер, чей читатель уже вышел (head закрывает поток).

  • ENAMETOOLONG (36)

    Слишком длинное имя файла. Обычно 255 байт на компонент; кириллица занимает по два байта на символ.

  • ENOTEMPTY (39)

    Каталог не пуст. rmdir работает только с пустым каталогом.

  • ELOOP (40)

    Слишком много уровней символических ссылок. Симлинк ссылается сам на себя по кругу.

  • ETIME (62)

    Истекло время таймера.

  • EADDRINUSE (98)

    Адрес уже используется. Порт занят. Найти виновника: ss -tulpn или lsof -i :порт. После падения помогает SO_REUSEADDR.

  • EADDRNOTAVAIL (99)

    Невозможно назначить адрес. Пытаетесь слушать IP, которого нет на интерфейсах.

  • ENETUNREACH (101)

    Сеть недоступна. Нет маршрута: ip r.

  • ECONNRESET (104)

    Соединение сброшено другой стороной. Собеседник закрыл сокет резко (RST). Часто это таймаут балансировщика или перезапуск бэкенда.

  • ETIMEDOUT (110)

    Истекло время ожидания. Пакеты уходят в никуда — обычно файрвол молча их дропает.

  • ECONNREFUSED (111)

    В соединении отказано. Порт закрыт: сервис не запущен или слушает только localhost.

  • EHOSTUNREACH (113)

    Хост недоступен.

  • EDQUOT (122)

    Превышена дисковая квота.