Scroll to navigation

sigreturn(2) System Calls Manual sigreturn(2)

ИМЯ

sigreturn, rt_sigreturn - выполняет возврат из обработчика сигнала и очищает кадр стека

LIBRARY

Standard C library (libc, -lc)

СИНТАКСИС

int sigreturn(...);

ОПИСАНИЕ

Если ядро Linux обнаруживает, что неблокированный сигнал ожидает обработки процессом, то при следующем переключении в пользовательский режим в этом процессе (например, при возврате из системного вызова или когда процесс перепланируется на ЦП), оно создаёт новый кадр в стеке пользовательского пространства, где сохраняет различные части контекста процесса (состояние слова процессора, регистры, маску сигналов и настройки стека сигналов).

Также ядро делает так, что при переходе в пользовательский режим вызывается обработчик сигналов и при возврате из обработчика управление передаётся части кода пользовательского пространства, называемого «сигнальным батутом»(signal trampoline). Код сигнального батута, в свою очередь, вызывает sigreturn().

Вызов sigreturn() очищает всё что накопилось — изменяет маску сигнала процесса, переключает стеки сигналов (см. sigaltstack(2)) — чтобы вызвать обработчик сигнала. Используя информацию, которая была ранее сохранена в стеке пользовательского пространства, sigreturn() восстанавливает маску сигналов процесса, переключает стеки и восстанавливает контекст процесса (регистры и флаги процессора, включая указатель стека и инструкций), так что процесс непосредственно возобновляет исполнение с точки где был прерван сигналом.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Вызов sigreturn() не возвращает значений.

СТАНДАРТЫ

Во многих системах UNIX есть системный вызов sigreturn() или его эквивалент. Однако этот вызов отсутствует в POSIX, и в разных системах он работает по-разному.

ЗАМЕЧАНИЯ

Вызов sigreturn() существует только для реализации обработчиков сигналов. Никогда не вызывайте его напрямую (на самом деле, простая обёртка sigreturn() в библиотеке GNU C просто вернёт -1 и присвоит errno значение ENOSYS). Содержимое аргументов (если есть), передаваемое sigreturn(), для каждой архитектуры своё (на некоторых архитектурах, например x86-64, у sigreturn() нет аргументов, так как вся требуемая информация доступна из кадра стека, который был создан ядром ранее в стеке пользовательского пространства).

Когда-то системы UNIX помещали код сигнального перехода в пользовательский стек. В настоящее время страницы пользовательского стека защищены и в них невозможно выполнить код. Поэтому в современных системах Linux, в зависимости от архитектуры, код хранится в vdso(7) или в библиотеке C. В последнем случае обёрточная функция sigaction(2) библиотеки C информирует ядро о расположении кода помещая его адрес в поле sa_restorer структуры sigaction и устанавливает флаг SA_RESTORER в поле sa_flags.

Сохранённая информация контекста процесса помещается в структуру ucontext_t (смотрите <sys/ucontext.h>). Эта структура видима внутри обработчика сигнала как третий аргумент обработчика, установленного sigaction(2) с флагом SA_SIGINFO.

В некоторых других системах UNIX работа сигнального батута несколько отличается. В частности, в некоторых системах при переходе в пользовательский режим ядро передаёт управление батуту (а не обработчику сигнала) и код батута вызывает обработчик сигнала (и затем вызывает sigreturn() после завершения работы обработчика).

Отличия между библиотекой C и ядром

Первоначальное название системного вызова в Linux было sigreturn(). Однако с добавлением сигналов реального времени в Linux 2.2 для поддержки увеличенного типа sigset_t был добавлен новый системный вызов rt_sigreturn(). Библиотека GNU C скрывает это от нас, прозрачно используя rt_sigreturn(), если он есть в ядре.

СМ. ТАКЖЕ

kill(2), restart_syscall(2), sigaltstack(2), signal(2), getcontext(3), signal(7), vdso(7)

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

4 декабря 2022 г. Linux man-pages 6.02