我需要一个glibc的异步信号安全功能列表

时间:2010-01-06 13:29:58

标签: linux list libc async-safe

非系统调用的包装器,但类似于snprintf(),dprintf()

4 个答案:

答案 0 :(得分:15)

我很确定你必须看到documentation

修改: 那么this list怎么样?

来自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 :(得分:1)

这似乎很难确定,因为您不知道库例程可能决定调用的随机不安全函数。不同版本的glibc之间的列表也可能不同,或者如果你把它带到另一个类Unix系统。好像你必须分析很多调用堆栈来找到答案,甚至从版本到版本,发行版到发行版可能有点摇摇欲坠。

也许你不是在寻找替代设计方法,但似乎更好的策略是:如果你的程序有一个事件循环,那么使信号处理程序非常愚蠢,只是设置一个事件循环将会获取的状态。这样你就可以在信号处理程序之外完成有意义的工作。

示例:假设您在某处有poll()循环。也许您可以包含信号处理程序可以写入的管道。然后poll()循环基于由此发出信号来完成一些非平凡的工作。

答案 2 :(得分:1)

最后, man 7 signal-safety 的最新版本包含感兴趣的列表:signal-safety.7.html

答案 3 :(得分:0)

  

在应用程序崩溃后我在SIGSEGV处理程序中需要这个。

     

我希望在崩溃时展开堆栈

如果您正在尝试捕获堆栈跟踪:

  • 通常abort会导致核心转储,可以通过调试器运行以产生堆栈跟踪。

  • 或者,粗略(但信号安全)这样做的方式是forkexec单独的实用程序(例如" pstack")输出崩溃任务的堆栈跟踪。在exec - (在孩子中fork之后),您需要使用getppid传递您的流程ID;在致电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()或raise()。

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

  

正常返回后,进程的行为是未定义的   SIGBUS,SIGFPE,SIGILL或SIGSEGV的信号捕获功能   不是由kill(),sigqueue()或raise()生成的信号。