Подтвердить что ты не робот

Мне нужен список функций безопасности Async-Signal Safe от glibc

Оболочки без syscall, но что-то вроде snprintf(), dprintf()

4b9b3361

Ответ 1

Наконец, последние версии man 7 signal-safety содержат интересующий список: signal-safety.7.html

Ответ 2

Я уверен, что вы должны увидеть документацию

Edit: Как насчет этот список, затем?

От 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.

Ответ 3

Это сложно определить, так как вы не знаете, какую случайную небезопасную функцию может использовать библиотечная процедура. Список также может отличаться от разных версий glibc, или если вы перейдете в другую Unix-подобную систему. Похоже, вам нужно проанализировать множество стеков вызовов, чтобы найти ответ, и даже это может быть немного шатким от версии к версии, дистрибутив к дистрибутиву.

Возможно, вы не ищете альтернативные подходы к дизайну, но похоже, что лучшей стратегией было бы: если ваша программа имеет цикл событий, сделайте обработчик сигнала очень глупым и просто установите какое-то состояние, которое будет зацикливаться на цикле событий. Таким образом, вы выполняете значимую работу вне обработчика сигнала.

Пример. Скажем, у вас есть цикл poll(). Возможно, вы могли бы включить канал, который может написать обработчик сигнала. Затем цикл poll() выполняет некоторую нетривиальную работу, основанную на сигнале от этого.

Ответ 4

Мне нужно это в обработчике SIGSEGV ПОСЛЕ аварии приложения.

Я хочу отключить стек при сбое

Если вы пытаетесь захватить трассировку стека:

  • Обычно abort вызывает основной дамп, который можно запустить через отладчик для создания трассировки стека.

  • В качестве альтернативы грубый (но безопасный для сигнала) способ сделать это будет fork и exec отдельной утилитой (например, "pstack" ) для вывода трассировки стека вашей разбитой задачи. Когда exec -ing (после fork -ing, у ребенка), вам необходимо передать идентификатор процесса с помощью getppid; и в родителе вам нужно wait завершить его, прежде чем вызывать abort.

С другой стороны, если вы пытаетесь выполнить "чистый" выход после SIGSEGV (например, чтобы вызвать деструкторы С++, вызывается и т.д.) - тогда вам следует предупредить, что POSIX говорит:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_02:

Поведение процесса undefined после игнорирования SIGFPE, SIGILL, SIGSEGV или SIGBUS, который не был создан kill(), sigqueue() или raise().

и http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03:

Поведение процесса undefined после того, как оно нормально возвращается из функция захвата сигнала для SIGBUS, SIGFPE, SIGILL или SIGSEGV сигнал, который не был создан kill(), sigqueue() или raise().