linux - Necesito una lista de funciones Async-Signal-Safe de glibc
async-safe (4)
Los contenedores de syscall, pero algo así como snprintf (), dprintf ()
Esto parece difícil de determinar, ya que no sabe qué función aleatoria insegura puede decidir llamar una rutina de biblioteca. La lista también puede ser diferente entre las diferentes versiones de glibc, o si lo lleva a otro sistema tipo Unix. Parece que tendrías que analizar muchas pilas de llamadas para encontrar la respuesta, e incluso eso puede ser un poco inestable de una versión a otra, distro a la distribución.
Tal vez no estés buscando enfoques de diseño alternativos, pero parece que una mejor estrategia sería: si tu programa tiene un ciclo de eventos, haz que el manejador de señal sea muy estúpido y simplemente establezca un estado que recupere el ciclo de evento. De esa forma, haces el trabajo significativo fuera del controlador de señal.
Ejemplo: Supongamos que tienes un bucle de poll()
alguna parte. Tal vez podrías incluir una tubería en la que el manejador de señal pueda escribir. Luego, el ciclo poll()
hace un trabajo no trivial basado en que lo señale.
Estoy bastante seguro de que tienes que ver la documentación
Editar : ¿Qué tal esta lista ?
De la man signal
:
NOTES
The effects of this call in a multi-threaded process are unspecified.
The routine handler must be very careful, since processing elsewhere
was interrupted at some arbitrary point. POSIX has the concept of "safe
function". If a signal interrupts an unsafe function, and handler
calls an unsafe function, then the behavior is undefined. Safe func-
tions are listed explicitly in the various standards. The POSIX.1-2003
list is
_Exit() _exit() abort() accept() access() aio_error() aio_return()
aio_suspend() alarm() bind() cfgetispeed() cfgetospeed() cfsetispeed()
cfsetospeed() chdir() chmod() chown() clock_gettime() close() connect()
creat() dup() dup2() execle() execve() fchmod() fchown() fcntl() fdata-
sync() fork() fpathconf() fstat() fsync() ftruncate() getegid()
geteuid() getgid() getgroups() getpeername() getpgrp() getpid() getp-
pid() getsockname() getsockopt() getuid() kill() link() listen()
lseek() lstat() mkdir() mkfifo() open() pathconf() pause() pipe()
poll() posix_trace_event() pselect() raise() read() readlink() recv()
recvfrom() recvmsg() rename() rmdir() select() sem_post() send()
sendmsg() sendto() setgid() setpgid() setsid() setsockopt() setuid()
shutdown() sigaction() sigaddset() sigdelset() sigemptyset() sig-
fillset() sigismember() signal() sigpause() sigpending() sigprocmask()
sigqueue() sigset() sigsuspend() sleep() socket() socketpair() stat()
symlink() sysconf() tcdrain() tcflow() tcflush() tcgetattr() tcgetp-
grp() tcsendbreak() tcsetattr() tcsetpgrp() time() timer_getoverrun()
timer_gettime() timer_settime() times() umask() uname() unlink()
utime() wait() waitpid() write().
According to POSIX, the behaviour of a process is undefined after it
ignores a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by
the kill(2) or the raise(3) functions. Integer division by zero has
undefined result. On some architectures it will generate a SIGFPE sig-
nal. (Also dividing the most negative integer by -1 may generate
SIGFPE.) Ignoring this signal might lead to an endless loop.
See sigaction(2) for details on what happens when SIGCHLD is set to
SIG_IGN.
The use of sighandler_t is a GNU extension. Various versions of libc
predefine this type; libc4 and libc5 define SignalHandler, glibc
defines sig_t and, when _GNU_SOURCE is defined, also sighandler_t.
Necesito esto en SIGSEGV handler DESPUÉS de la falla de la aplicación.
Quiero desenrollar la pila en crash
Si intenta capturar un rastro de pila:
Normalmente,
abort
causaría un volcado del núcleo, que se puede ejecutar a través de un depurador para producir el seguimiento de la pila.Alternativamente, una forma cruda (pero segura de señal) de hacerlo sería
fork
yexec
una utilidad separada (por ejemplo, "pstack") para generar un seguimiento de la pila de su tarea bloqueada. Al ejecutar (después defork
, en el niño), tendrá que pasar su identificación del proceso usandogetppid
; y en el padre tendrá quewait
a que termine, antes de llamar aabort
.
Por otro lado, si intenta hacer una salida "limpia" después de SIGSEGV (por ejemplo, asegurando que se llame a los destructores de C ++, etc.), entonces se le debe advertir que POSIX dice:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_02 :
El comportamiento de un proceso no está definido después de ignorar una señal SIGFPE, SIGILL, SIGSEGV o SIGBUS que no fue generada por kill (), sigqueue () o raise ().
y http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03 :
El comportamiento de un proceso no está definido después de que regrese normalmente de una función de captura de señal para una señal SIGBUS, SIGFEG, SIGILL o SIGSEGV que no fue generada por kill (), sigqueue () o raise ().
Finalmente, las últimas versiones de man 7 signal-safety
contienen la lista de interesados: signal-safety.7.html