2016-06-15 2 views
3

Я зарегистрировал обработчик SIGSEGV, используя fprintf, чтобы напечатать некоторое сообщение, а затем выйти. Процесс распечатывает сообщение, но не выходит. Он заблокирован до exit().Обработчик SIGSEGV не может выйти

Не могу использовать exit(), чтобы закончить процесс, как правило, в обработчике?

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

избежать Printf в обработчике сигнала, вы будете наслаждаться чтением это [ «Использование реентрантных функций для безопасного обращения сигнала»] (HTTP: //www.ibm.com/developerworks/linux/library/l-reent/index.html#N101CA) –

ответ

5

Не могу использовать exit() для нормального завершения процесса в обработчике?

exit() не следует вызывать из обработчика сигнала, так как он не гарантирован безопасностью для асинхронного сигнала. Используйте вместо этого _exit(), _Exit() или abort().

При этом printf() не следует вызывать из обработчика сигнала по той же причине, что и для exit().

Полного список функций, являющиеся асинхронный сигнал безопасный или нет пожалуйста, смотрите вниз на этой странице:


Более того, в тот момент, когда произошло нарушение сегментации, программа нестабильна или даже сломана, стек может меня разбить, поэтому нет никакой гарантии, что что-либо можно назвать все с этого момента.

2

В контролируемых условиях это возможно, но в целом нет. Функция exit пытается выполнить чистое завершение работы и требует, чтобы процесс находился в нормальном состоянии. Поскольку SIGSEGV был сгенерирован, но не обработан, код, скорее всего, не находится в нормальном состоянии, поэтому не гарантируется бесперебойное завершение работы. В этих обстоятельствах используйте _exit.

Ваш звонок в fprintf также не рекомендуется. Используйте write.

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() 
+0

Большое спасибо! Я использую 'kill()' вместо 'exit()'. –

Смежные вопросы