From owner-freebsd-hackers Wed Feb 19 20:37: 4 2003 Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 81C0237B401 for ; Wed, 19 Feb 2003 20:37:01 -0800 (PST) Received: from heron.mail.pas.earthlink.net (heron.mail.pas.earthlink.net [207.217.120.189]) by mx1.FreeBSD.org (Postfix) with ESMTP id DDFD243F75 for ; Wed, 19 Feb 2003 20:37:00 -0800 (PST) (envelope-from tlambert2@mindspring.com) Received: from pool0298.cvx22-bradley.dialup.earthlink.net ([209.179.199.43] helo=mindspring.com) by heron.mail.pas.earthlink.net with asmtp (SSLv3:RC4-MD5:128) (Exim 3.33 #1) id 18liS5-0001hY-00; Wed, 19 Feb 2003 20:36:54 -0800 Message-ID: <3E545B0C.9DB2FB03@mindspring.com> Date: Wed, 19 Feb 2003 20:35:24 -0800 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: Vaclav Haisman Cc: freebsd-hackers@freebsd.org Subject: Re: Raising SIGSEGV in SIGSEGV handler makes FreeBSD loop References: <20030220032757.S96729-100000@logout.sh.cvut.cz> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-ELNK-Trace: b1a02af9316fbb217a47c185c03b154d40683398e744b8a40808458ff4ceac8edb1128aad2afd506350badd9bab72f9c350badd9bab72f9c350badd9bab72f9c Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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