SIGSEGV处理程序无法退出

时间:2016-06-15 07:59:52

标签: c linux unix segmentation-fault signals

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

我不能使用exit()在处理程序中正常完成该过程吗?

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

3 个答案:

答案 0 :(得分:5)

  

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

不应该从信号处理程序调用

exit(),因为它不能保证异步信号安全。请改用_exit()_Exit()abort()

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

有关async-signal-safe与否的完整功能列表,请查看此页面:

此外,当分段违规发生时,程序不稳定,甚至破坏,堆栈可能会被粉碎,因此无法保证从那一刻开始可以调用任何东西。

答案 1 :(得分:2)

在受控条件下,这可能是可能的,但总的来说,没有。 exit函数尝试执行干净关闭,并要求进程处于正常状态。由于生成了SIGSEGV但未处理,因此代码可能不处于正常状态,因此无法保证干净关闭。在这些情况下使用_exit

您的fprintf电话也不明智。使用write

答案 2 :(得分:0)

The list of functions POSIX requires是异步信号安全的:

  

下表定义了一组应该是的函数   异步信号安全。因此,应用程序可以调用它们,而不需要   限制,来自信号捕捉功能:

_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()