非系统调用的包装器,但类似于snprintf(),dprintf()
答案 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
会导致核心转储,可以通过调试器运行以产生堆栈跟踪。
或者,粗略(但信号安全)这样做的方式是fork
和exec
单独的实用程序(例如" 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()生成的信号。