SIGSEGV处理程序不能退出

我注册了SIGSEGV处理程序,使用fprintf打印一些消息,然后退出。 该进程打印消息,但没有退出。 它在exit()之前被阻塞。

我不能使用exit()在处理程序中正常结束进程吗?

 void sigsegv__handler(){ fprintf(stderr, "SIGSEGV , TID: %d,PID: %d\n", TEST_ID, getpid()); exit(1); } 

我不能使用exit()来正常完成处理程序中的进程吗?

不应该从信号处理程序调用exit()因为它不保证是异步信号安全的。 使用_exit()_Exit()或者abort()来代替。

也就是说, printf()不应该从信号处理程序调用,这与应用于exit()原因相同。

有关异步信号安全的功能的完整列表,请看下面的页面:

  • Linux: http : //man7.org/linux/man-pages/man7/signal.7.html
  • POSIX: http : //pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03

而且,当发生分割违规的时候,程序是不稳定的,甚至是破碎的,堆栈可能会被捣毁,所以不能保证从那时起什么都可以被调用。

在受控制的条件下,这可能是可能的,但总的来说,没有。 exit函数尝试执行干净关闭,并要求进程处于正常状态。 由于生成了一个SIGSEGV,但没有处理,代码可能不是一个健全的状态,所以干净的关闭不能保证工作。 在这种情况下使用_exit

您也打电话给fprintf 。 使用write

POSIX函数列表要求是异步信号安全的:

下表定义了一组应该是异步信号安全的函数。 因此,应用程序可以从信号捕获功能中无限制地调用它们:

 _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() execl() execle() execv() execve() faccessat() fchdir() fchmod() fchmodat() fchown() fchownat() fcntl() fdatasync() fexecve() fork() fstat() fstatat() fsync() ftruncate() futimens() getegid() geteuid() getgid() getgroups() getpeername() getpgrp() getpid() getppid() getsockname() getsockopt() getuid() kill() link() linkat() listen() lseek() lstat() mkdir() mkdirat() mkfifo() mkfifoat() mknod() mknodat() open() openat() pause() pipe() poll() posix_trace_event() pselect() pthread_kill() pthread_self() pthread_sigmask() raise() read() readlink() readlinkat() recv() recvfrom() recvmsg() rename() renameat() rmdir() select() sem_post() send() sendmsg() sendto() setgid() setpgid() setsid() setsockopt() setuid() shutdown() sigaction() sigaddset() sigdelset() sigemptyset() sigfillset() sigismember() signal() sigpause() sigpending() sigprocmask() sigqueue() sigset() sigsuspend() sleep() sockatmark() socket() socketpair() stat() symlink() symlinkat() tcdrain() tcflow() tcflush() tcgetattr() tcgetpgrp() tcsendbreak() tcsetattr() tcsetpgrp() time() timer_getoverrun() timer_gettime() timer_settime() times() umask() uname() unlink() unlinkat() utime() utimensat() utimes() wait() waitpid() write()