Источники сигналов: аппаратура, ядро, программист

⏱ 30 мин · 🧩 заданий: 5

Откуда берутся сигналы

Любой сигнал можно послать вызовом kill, но у каждого есть типичный источник — событие, ради которого сигнал придуман. Это и спрашивают в задаче 1.

АППАРАТУРА ЯДРО ТЕРМИНАЛ ПРОГРАММА исключения CPU программные события драйвер tty kill(), raise(), ─────────────── ────────────────── ────────── abort(), sigqueue() SIGSEGV SIGBUS SIGCHLD SIGPIPE SIGINT SIGQUIT SIGUSR1 SIGUSR2 SIGFPE SIGILL SIGALRM SIGXCPU SIGTSTP SIGTTIN SIGABRT SIGTERM SIGTRAP SIGURG SIGIO SIGTTOU SIGHUP SIGKILL SIGSTOP SIGXFSZ SIGSYS SIGWINCH SIGCONT SIGRTMIN…

1. Аппаратные исключения

Процессор не смог выполнить инструкцию → исключение → обработчик ядра → сигнал тому потоку, который выполнил инструкцию. Это синхронные сигналы.

Исключение процессора Сигнал Пример
страничный отказ на недопустимом адресе / нарушение прав SIGSEGV *NULL = 1, запись в .rodata, переполнение стека
ошибка шины: невыровненный доступ (на строгих архитектурах), за концом отображённого файла, аппаратная ошибка памяти SIGBUS mmap файла и обращение за его концом
деление целого на ноль, переполнение при делении SIGFPE 1 / 0, INT_MIN / -1
недопустимая или привилегированная инструкция SIGILL порча кода, инструкция новее процессора
точка останова, пошаговое выполнение SIGTRAP работа отладчика

Почему это «связано с аппаратным событием»

Первоисточник — сам процессор: он обнаружил проблему при выполнении инструкции и сгенерировал исключение. Ядро лишь переводит исключение в сигнал. Для таблицы задачи 1 это SIGBUS и SIGFPE (а также SIGSEGV и SIGILL, если встретятся).

Если такой сигнал заблокирован или игнорируется в момент исключения, Linux всё равно убивает процесс: продолжать выполнение с той же инструкции бессмысленно — исключение повторится.

2. Программные события ядра

Ядро сообщает процессу о событии, не связанном с ошибкой процессора:

Сигнал Событие По умолчанию
SIGCHLD потомок завершился, остановился или продолжил работу Ign
SIGPIPE запись в канал/сокет без читателей Term
SIGALRM истёк таймер alarm() / setitimer Term
SIGXCPU, SIGXFSZ превышен лимит процессорного времени / размера файла Core
SIGURG срочные данные в сокете Ign
SIGIO ввод-вывод возможен (асинхронный режим) Term
SIGSYS недопустимый системный вызов (seccomp) Core
SIGKILL убийца нехватки памяти (OOM killer) выбрал процесс Term

SIGCHLD — самый частый: именно так родитель узнаёт, что пора вызвать wait.

3. Драйвер терминала

Терминал — тоже часть ядра. Он превращает специальные символы и ситуации в сигналы активной группе процессов (или конкретной группе):

Ситуация Сигнал По умолчанию
Ctrl+C SIGINT Term
Ctrl+\ SIGQUIT Core
Ctrl+Z SIGTSTP Stop
фоновая группа читает терминал SIGTTIN Stop
фоновая группа пишет (при tostop) или меняет настройки SIGTTOU Stop
терминал закрыт / сеанс потерял терминал SIGHUP Term
изменился размер окна SIGWINCH Ign

Символы настраиваются: stty -a покажет intr = ^C; quit = ^\; susp = ^Z.

4. Явная отправка программистом

Некоторые сигналы существуют только для того, чтобы их посылали программы:

Сигнал Как и зачем
SIGUSR1, SIGUSR2 смысл задаёт программа: «перечитать конфигурацию», «переоткрыть журнал»
SIGABRT abort() — аварийное завершение по решению самой программы (так срабатывает неудачный assert)
SIGTERM просьба завершиться: kill pid, init при выключении
SIGKILL безусловное уничтожение: kill -9 pid (также OOM killer ядра)
SIGSTOP безусловная остановка: kill -STOP pid, отладчик
SIGCONT продолжение: kill -CONT pid, shell по командам fg/bg
SIGRTMIN…SIGRTMAX сигналы реального времени: sigqueue(pid, sig, value) с данными
#include <assert.h>
assert(ptr != NULL);     /* если ложно: сообщение и abort() → SIGABRT → core dump */

Итог

  • Аппаратные исключения → SIGSEGV, SIGBUS, SIGFPE, SIGILL, SIGTRAP (синхронно, потоку-виновнику).
  • Программные события ядра → SIGCHLD, SIGPIPE, SIGALRM, SIGXCPU, SIGURG.
  • Драйвер терминала → SIGINT, SIGQUIT, SIGTSTP, SIGTTIN, SIGTTOU, SIGHUP, SIGWINCH.
  • По инициативе программиста → SIGUSR1/2, SIGABRT (через abort), SIGTERM, SIGKILL, SIGSTOP, SIGCONT, сигналы реального времени.

Практика решено 0 из 5

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Заполнить таблицу

Какой основной источник у каждого сигнала?

Аппаратное исключениеПрограммное событие ядраДрайвер терминалаЯвно программа или пользователь
SIGSEGV
SIGFPE
SIGBUS
SIGCHLD
SIGPIPE
SIGALRM
SIGINT
SIGTTIN
SIGUSR2
SIGABRT
SIGRTMIN
Отметьте ячейку — «+», пустая — «−».
Задание 2 Ввод ответа

Что произойдёт с программой? (ответ — имя сигнала)

int a = 1, b = 0;
printf("%d\n", a / b);
Задание 3 Один вариант ответа

Программа отобразила файл размером 100 байт через mmap на 2 страницы и обращается ко второй странице. Какой сигнал она получит?

Задание 4 Один вариант ответа

Когда ядро посылает процессу SIGPIPE?

Задание 5 Несколько вариантов

Когда процесс-родитель получает SIGCHLD?

Войдите, чтобы отмечать пройденные уроки.