sigaltstack(2) definir y/u obtener el contexto de la pila de señales

SINOPSIS

#include <signal.h>

int sigaltstack(const stack_t *ss, stack_t *oss);

DESCRIPCIÓN

sigaltstack permite a un proceso definir una nueva pila alternativa de señales y/o recuperar el estado de una pila alternativa de señales existente. Una pila alternativa de señales se usa durante la ejecución de un manejador de señales si el establecimiento de ese manejador (ver sigaction(2)) lo solicita.

La secuencia normal de eventos para usar una pila alternativa de señales es la siguiente:

1.
Reservar un área de memoria para ser utilizada por la pila alternativa de señales.
2.
Utilizar sigaltstack para informar al sistema de la existencia y la localización de la pila alternativa de señales.
3.
Cuando se establece un manejador de señales usando sigaction, informar al sistema de que el manejador de señales debería ser ejecutado en la pila alternativa de señales, especificando la bandera SA_ONSTACK.

El argumento ss se usa para especificar una nueva pila alternativa de señales, mientras que el argumento oss se usa para recuperar información sobre la pila alternativa de señales establecida actualmente. Si estamos interesados en realizar sólo una de estas tareas, entonces el otro argumento se puede especificar como NULL. Cada uno de estos argumentos es una estructura del tipo siguiente:

typedef struct {
    void  *ss_sp;     /* Dirección de la base de la pila */
    int    ss_flags;  /* Banderas */
    size_t ss_size;   /* Numero de bytes en la pila */
} stack_t;

Para establecer una nueva pila alternativa de señales, ss.ss_flags se inicializa a cero, ss.ss_sp y ss.ss_size especifican la dirección de comienzo y el tamaño de la pila. La constante SIGSTKSZ se define para ser suficientemente grande para cubrir el requerimiento de tamaño habitual en una pila alternativa de señales, y la constante MINSIGSTKSZ define el tamaño mínimo requerido para ejecutar un manejador de señales.

Para deshabilitar una pila existente, se especifica ss.ss_flags como SS_DISABLE. En este caso, los campos restantes en ss se ignoran.

Si oss no es NULL, entonces se utiliza para devolver información sobre la pila alternativa de señales que estaba en uso antes de la llamada a sigaltstack. Los campos oss.ss_sp y oss.ss_sizedevuelven la dirección de comienzo y el tamaño de esa pila. El oss.ss_flags puede devolver cualquiera de los siguientes valores:

SS_ONSTACK
El proceso está actualmente ejecutándose en la pila alternativa de señales. (Nótese que no es posible cambiar la pila alternativa de señales si el proceso está ejecutándose en ella.)
SS_DISABLE
La pila alternativa de señales está actualmente deshabilitada.

VALOR DEVUELTO

sigaltstack devuelve 0 en caso de éxito, o -1 en caso de error, con errno definido para indicar el error.

ERRORES

ENOMEM
El tamaño especificado para la nueva pila alternativa de señales (ss.ss_size) era menor que MINSTKSZ.
EFAULT
Ya sea ss o oss no es NULL y apunta a un área fuera del espacio de direcciones del proceso.
EPERM
Hubo un intento de cambiar la pila alternativa de señales mientras estaba activa (p.e.: el proceso ya estaba ejecutándose en la pila alternativa de señales actual).
EINVAL
ss no es NULL y el campo ss_flags contiene un valor distinto de cero y de SS_DISABLE.

OBSERVACIONES

El código siguiente muestra el uso de sigaltstack:

stack_t ss;
ss.ss_sp = malloc(SIGSTKSZ);
if (ss.ss_sp == NULL)
    /* Manejar error */;
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) == -1)
    /* Manejar error */;

Establecer una pila alternativa de señales es útil si un proceso espera agotar su pila estándar. Esto puede ocurrir, por ejemplo, porque la pila crezca tanto que se encuentre con el montículo, que crece hacia arriba, o que alcance un límite establecido por una llamada a setrlimit(RLIMIT_STACK, &rlim). Si la pila estándar se agota, el núcleo envía al proceso una señal SIGSEGV. En estas circunstancias, la única manera de capturar esta señal es en una pila alternativa de señales.

En la mayoría de las arquitecturas aceptadas por Linux, las pilas crecen hacia abajo. sigaltstack reconoce automáticamente la dirección de crecimiento.

Las funciones llamadas desde un manejador de señales que se ejecute en una pila alternativa de señales también usarán la pila alternativa de señales. (Esto también es aplicable a cualesquiera manejadores invocados para otras señales mientras el proceso se está ejecutando en la pila alternativa de señales.) De manera diferente a la pila estándar, el sistema no extiende automáticamente la pila alternativa de señales. Exceder el tamaño reservado de la pila alternativa de señales conlleva resultados impredecibles.

Una llamada exitosa a execve elimina cualquier pila alternativa de señales existente.

sigaltstack sustituye la antigua llamada sigstack. Para la compatibilidad hacia atrás, glibc también ofrece sigstack. Todas las aplicaciones nuevas deberían ser usadas usando sigaltstack.

HISTORIA

BSD 4.2 tenía una llamada al sistema sigstack(). Usaba una estructura ligeramente diferente, y como una desventaja mayor, el invocador debía saber la dirección de crecimiento de la pila.

CONFORME A

SUSv2, SVr4, POSIX 1003.1-2001.