Date: Wed, 19 Feb 2003 20:35:24 -0800 From: Terry Lambert <tlambert2@mindspring.com> To: Vaclav Haisman <V.Haisman@sh.cvut.cz> Cc: freebsd-hackers@freebsd.org Subject: Re: Raising SIGSEGV in SIGSEGV handler makes FreeBSD loop Message-ID: <3E545B0C.9DB2FB03@mindspring.com> References: <20030220032757.S96729-100000@logout.sh.cvut.cz>
next in thread | previous in thread | raw e-mail | index | archive | help
Vaclav Haisman wrote: > > If you want this to not happen, you should explicitly uninstall the > > handler, or you should call abort(3) (or _exit(2), if you don't want > > to leave a core dump). > > Even though this is probably about my misunderstanding of things I post here > the test I used. [ ... ] > void handler (int, siginfo_t * info, ucontext_t * uap) > { > std::cerr << "SIGSEGV has been caught" << std::endl; > struct sigaction mysig; > mysig.sa_handler = SIG_DFL; > mysig.sa_sigaction = NULL; > mysig.sa_flags = 0; > if (sigaction(SIGSEGV, &mysig, NULL) == -1) > { > std::cerr << "Error in sigaction()" << std::endl; > abort(); > } > > f((int*)NULL); This is not legal. > /*mysig.sa_handler = SIG_DFL; [ ... commented out handler reset code ... ] I don't understand why you do this. Performing a NULL pointer dereference in a signal handler for a signal which is generated by a NULL pointer dereference is not really a good idea. The signal handler, once entered, masks the signal. It's possible that the signal handler itself is reset on exit (this is implementation defined). The main problem here is that signals are not events, they are persistent conditions. FreeBSD does not support POSIX queued signals, at this time, so it's not possible to treat them as events under any circumstances. Though there may be issues with stack unwinding, with C++, I don't think that's your problem. You could try implementing the same program in C, and determine if it has the same symptoms. You may also try adding: memset( &mysig, 0, sizeof(struct sigaction)); after the declaration, but prior to your use of the stack variable. Specifically, I do not see you setting the sa_mask structure member anywhere, and that could be Bad(tm), particularly if you were setting masking on the signal that triggered the call, and then re-triggering it. It's conceivable that the implementation would check the sa_mask before resetting the handler. Also, note that any use of functions not in this list: Base Interfaces exit() access() alarm() cfgetispeed() cfgetospeed() cfsetispeed() cfsetospeed() chdir() chmod() chown() close() creat() dup() dup2() execle() execve() fcntl() fork() fpathconf() fstat() fsync() getegid() geteuid() getgid() getgroups() getpgrp() getpid() getppid() getuid() kill() link() lseek() mkdir() mkfifo() open() pathconf() pause() pipe() raise() read() rename() rmdir() setgid() setpgid() setsid() setuid() sigaction() sigaddset() sigdelset() sigemptyset() sigfillset () sigismember() signal() sigpending() sigprocmask() sigsuspend() sleep() stat() sysconf() tcdrain() tcflow() tcflush() tcgetattr() tcgetpgrp() tcsendbreak() tcsetattr() tcsetpgrp() time() times() umask() uname() unlink() utime() wait() waitpid() write() Realtime Interfaces aio_error() clock_gettime() sigpause() timer_getoverrun() aio_return() fdatasync() sigqueue() timer_gettime() aio_suspend() sem_post() sigset() timer_settime() are specifically considered "unsafe" by POSIX, and their behaviour is undefined. Specifically: All functions not in the above table are considered to be unsafe with respect to signals. In the presence of signals, all functions defined by this specification will behave as defined when called from or interrupted by a signal-catching function, with a single exception: when a signal interrupts an unsafe function and the signal-catching function calls an unsafe function, the behaviour is undefined. I'd say that was exactly the case you were testing with the function "f", and by using "cout" to do I/O in the handler. -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3E545B0C.9DB2FB03>