Мне нужен список асинхронно-безопасных функций от glibc - PullRequest
13 голосов
/ 06 января 2010

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

Ответы [ 4 ]

15 голосов
/ 13 января 2010

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

Редактировать : Как насчет этот список тогда?

С 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.
1 голос
/ 14 сентября 2017

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

1 голос
/ 18 января 2010

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

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

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

0 голосов
/ 30 ноября 2014

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

Я хочу отмотать стек при сбое

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

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

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

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

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

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

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

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

...