Provided by: manpages-ru-dev_4.21.0-2_all bug

ИМЯ

       sigaltstack - считывает или устанавливает расположение стека сигналов

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <signal.h>

       int sigaltstack(const stack_t *_Nullable restrict ss,
                       stack_t *_Nullable restrict old_ss);

   Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

       sigaltstack():
           _XOPEN_SOURCE >= 500
               || /* начиная с glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
               || /* glibc <= 2.19: */ _BSD_SOURCE

ОПИСАНИЕ

       sigaltstack()   allows a thread to define a new alternate signal stack and/or retrieve the
       state of an existing alternate signal stack.  An alternate signal stack is used during the
       execution  of  a  signal  handler  if the establishment of that handler (see sigaction(2))
       requested it.

       Обычный порядок действий для использования альтернативного стека сигналов:

       1. Выделить область памяти, которая будет использована под альтернативный стек сигналов.

       2. Вызвать  sigaltstack()  для  информирования  системы  о  существовании  и  расположении
          альтернативного стека сигналов.

       3. При  установке обработчика сигналов с помощью sigaction(2) (флагом SA_ONSTACK) сообщить
          системе, что обработчик сигналов должен выполняться с альтернативным стеком сигналов.

       Аргумент ss используется для указания нового альтернативного стека  сигналов,  а  аргумент
       old_ss  используется  для  получения  информации  об  установленном  в данный момент стеке
       сигналов. Если интересует какая-то одна из этих задач, то другой аргумент указывается  как
       NULL.

       Тип stack_t, используемый для аргументов этой функции, определён следующим образом:

           typedef struct {
               void  *ss_sp;     /* базовый адрес стека */
               int    ss_flags;  /* флаги */
               size_t ss_size;   /* количество байт в стеке */
           } stack_t;

       Для  организации  нового  альтернативного  стека  сигналов поля этой структуры должны быть
       заполнены следующим образом:

       ss.ss_flags
              В этом поле содержится 0 или следующий флаг:

              SS_AUTODISARM (начиная с Linux 4.7)
                     Очистить настройки  альтернативного  стека  сигналов  в  записи  обработчика
                     сигналов.    Когда    происходит    возврат    из    обработчика   сигналов,
                     восстанавливаются предыдущие настройки альтернативного стека сигналов.

                     Этот флаг был добавлен для безопасного переключения из обработчика  сигналов
                     с  помощью  swapcontext(3).  Без этого флага следующий обрабатываемый сигнал
                     повредит состояние обработчика сигналов, в который выполняется  переключение
                     (switched-away).  В  ядрах  без  поддержки  этого  флага вызов sigaltstack()
                     завершается ошибкой EINVAL, если этот флаг указан.

       ss.ss_sp
              Это  поле  задаёт  начальный  адрес  стека.  При  вызове  обработчика   сигнала   с
              альтернативным  стеком  ядро автоматически выравнивает адрес, указанный в ss.ss_sp,
              по границе адреса, подходящей для используемой аппаратной платформы.

       ss.ss_size
              В этом поле задаётся размер стека. Для определения альтернативного  стека  сигналов
              достаточного  размера  можно использовать константу SIGSTKSZ, а для выделения стека
              минимального размера можно указать константу MINSIGSTKSZ.

       Для отключения существующего стека, укажите в  ss.ss_flags  значение  SS_DISABLE.  В  этом
       случае ядро игнорирует все флаги в ss.ss_flags и остальные поля в ss.

       Если  old_ss  не  равно  NULL,  то  в  нём возвращается информация об альтернативном стеке
       сигналов, который использовался до этого вызова  sigaltstack().  В  полях  old_ss.ss_sp  и
       old_ss.ss_size  возвращаются  начальный адрес и размер стека. В old_ss.ss_flags может быть
       возвращено одно из следующих значений:

       SS_ONSTACK
              The thread is currently executing on the alternate signal stack.  (Note that it  is
              not  possible  to  change  the  alternate  signal  stack if the thread is currently
              executing on it.)

       SS_DISABLE
              В данный момент альтернативный стек сигналов выключен.

              Alternatively, this value is returned if the thread is currently  executing  on  an
              alternate  signal stack that was established using the SS_AUTODISARM flag.  In this
              case, it is safe to switch away from the signal handler with swapcontext(3).  It is
              also  possible  to set up a different alternative signal stack using a further call
              to sigaltstack().

       SS_AUTODISARM
              Альтернативный стек сигналов был помечен к автоматической  очистке  (autodisarmed),
              как описывалось ранее.

       Если  присвоить  ss  значение NULL,а old_ss — не NULL, то можно получить текущие настройки
       альтернативного стека сигналов без его изменения.

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

       При успешном выполнении sigaltstack() возвращается 0. В случае ошибки возвращается  -1,  а
       errno устанавливается в соответствующее значение.

ОШИБКИ

       EFAULT Значение  ss или old_ss не равно NULL и указывает за пределы адресного пространства
              процесса.

       EINVAL Значение ss не равно NULL и в поле ss_flags содержится некорректный флаг.

       ENOMEM Указанный  размер  нового  альтернативного   стека   сигналов   ss.ss_size   меньше
              MINSIGSTKSZ.

       EPERM  An attempt was made to change the alternate signal stack while it was active (i.e.,
              the thread was already executing on the current alternate signal stack).

АТРИБУТЫ

       Описание терминов данного раздела смотрите в attributes(7).

       ┌───────────────────────────────────────────────────────┬──────────────────────┬──────────┐
       │ИнтерфейсАтрибутЗначение │
       ├───────────────────────────────────────────────────────┼──────────────────────┼──────────┤
       │sigaltstack()                                          │ Безвредность в нитях │ MT-Safe  │
       └───────────────────────────────────────────────────────┴──────────────────────┴──────────┘

СТАНДАРТЫ

       POSIX.1-2001, POSIX.1-2008, SUSv2, SVr4.

       Флаг SS_AUTODISARM является расширением Linux.

ЗАМЕЧАНИЯ

       The most common usage of an alternate signal stack is to handle the SIGSEGV signal that is
       generated  if  the  space  available  for the standard stack is exhausted: in this case, a
       signal handler for SIGSEGV cannot be invoked on the standard stack; if we wish  to  handle
       it, we must use an alternate signal stack.

       Establishing  an  alternate signal stack is useful if a thread expects that it may exhaust
       its standard stack.  This may occur, for example, because the stack grows so large that it
       encounters  the  upwardly  growing  heap,  or  it reaches a limit established by a call to
       setrlimit(RLIMIT_STACK, &rlim).  If the standard stack is exhausted, the kernel sends  the
       thread  a  SIGSEGV signal.  In these circumstances the only way to catch this signal is on
       an alternate signal stack.

       На большинстве аппаратных архитектур, поддерживаемых  Linux,  стеки  растут  сверху  вниз.
       Вызов sigaltstack() автоматически учтёт направление роста стека.

       Functions  called  from  a signal handler executing on an alternate signal stack will also
       use the alternate signal stack.  (This also applies to  any  handlers  invoked  for  other
       signals while the thread is executing on the alternate signal stack.)  Unlike the standard
       stack, the system does not automatically extend the alternate signal stack.  Exceeding the
       allocated size of the alternate signal stack will lead to unpredictable results.

       A  successful  call  to  execve(2)   removes any existing alternate signal stack.  A child
       process created via fork(2)  inherits a  copy  of  its  parent's  alternate  signal  stack
       settings.   The  same  is also true for a child process created using clone(2), unless the
       clone flags include CLONE_VM and do not include CLONE_VFORK, in which case  any  alternate
       signal stack that was established in the parent is disabled in the child process.

       Вызов  sigaltstack()  заменяет  устаревший  вызов sigstack(). Для обратной совместимости в
       glibc также  есть  функция  sigstack().  Во  всех  новых  приложениях  нужно  использовать
       sigaltstack().

   История
       Системный  вызов  sigstack()  появился  в  4.2BSD.  В  нём  использовалась  слегка  другая
       структура, и его  главным  недостатком  было  то,  что  вызывающий  должен  был  учитывать
       направления роста стека.

ДЕФЕКТЫ

       В  Linux  2.2  и старее в ss.sa_flags можно указывать только флаг SS_DISABLE. В версиях до
       ядра Linux 2.4  разрешалось  sigaltstack()  допускать  ss.ss_flags==SS_ONSTACK  с  тем  же
       смыслом  как  ss.ss_flags==0  (т.  е., при включении SS_ONSTACK в ss.ss_flags ни к чему не
       приводило).  В  других  реализациях  и  согласно  POSIX.1  флаг  SS_ONSTACK  появляется  в
       old_ss.ss_flags  только  как  флаг  результата.  В  Linux  его  не  нужно даже указывать в
       ss.ss_flags, иначе это снизит переносимость, так как некоторые системы выдают ошибку, если
       в ss.ss_flags указан SS_ONSTACK.

ПРИМЕРЫ

       В  следующем  сегменте  кода  показано  использование  sigaltstack()  (и sigaction(2)) для
       установки альтернативного стека сигналов, который используется  обработчиком  для  сигнала
       SIGSEGV:

           stack_t ss;

           ss.ss_sp = malloc(SIGSTKSZ);
           if (ss.ss_sp == NULL) {
               perror("malloc");
               exit(EXIT_FAILURE);
           }

           ss.ss_size = SIGSTKSZ;
           ss.ss_flags = 0;
           if (sigaltstack(&ss, NULL) == -1) {
               perror("sigaltstack");
               exit(EXIT_FAILURE);
           }

           sa.sa_flags = SA_ONSTACK;
           sa.sa_handler = handler();      /* адрес обработчика сигналов */
           sigemptyset(&sa.sa_mask);
           if (sigaction(SIGSEGV, &sa, NULL) == -1) {
               perror("sigaction");
               exit(EXIT_FAILURE);
           }

СМ. ТАКЖЕ

       execve(2), setrlimit(2), sigaction(2), siglongjmp(3), sigsetjmp(3), signal(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 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

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