3

I registered a handler of SIGSEGV, using fprintf to print some message then exit. The process prints the message but did not exit. It blocked before exit().

Can't I use exit() to finish the process normally in the handler?

void sigsegv__handler(){
    fprintf(stderr, "SIGSEGV , TID: %d,PID: %d\n", TEST_ID, getpid());
    exit(1);
}
wangbo15
  • 191
  • 1
  • 13
  • avoid printf in signal handler, you will enjoy reading this ["Use reentrant functions for safer signal handling"](http://www.ibm.com/developerworks/linux/library/l-reent/index.html#N101CA) – Grijesh Chauhan Jun 15 '16 at 08:12

3 Answers3

5

Can't I use exit() to normal finish the process in the handler?

exit() should not be called from a signal handler as it isn't guaranteed to be async-signal-safe. Use _exit(), _Exit() or abort() instead.

That said, printf() should not be called from a signal handler for the same reason that applies to exit().

For a full list of functions being async-signal-safe or not please have look down on this pages:


Moreover, the moment a segmentation violation occured the program is unstable, or even broken, the stack may me smashed, so there is no guarantee that anything may be called at all from that moment on.

alk
  • 69,737
  • 10
  • 105
  • 255
2

Under controlled conditions it may be possible, but in general, no. The exit function tries to do a clean shutdown and requires the process to be in a sane state. Since a SIGSEGV was generated but not handled, the code is likely not in a sane state, so a clean shutdown is not guaranteed to work. Use _exit in these circumstances.

Your call to fprintf is ill advised as well. Use write.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0

The list of functions POSIX requires to be async-signal-safe are:

The following table defines a set of functions that shall be async-signal-safe. Therefore, applications can invoke them, without restriction, from signal-catching functions:

_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()
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56