From owner-cvs-all@FreeBSD.ORG Mon Nov 10 00:27:51 2003 Return-Path: Delivered-To: cvs-all@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5C95316A4CF; Mon, 10 Nov 2003 00:27:51 -0800 (PST) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7AC4343FCB; Mon, 10 Nov 2003 00:27:48 -0800 (PST) (envelope-from bde@zeta.org.au) Received: from gamplex.bde.org (katana.zip.com.au [61.8.7.246]) by mailman.zeta.org.au (8.9.3p2/8.8.7) with ESMTP id TAA22726; Mon, 10 Nov 2003 19:27:29 +1100 Date: Mon, 10 Nov 2003 19:27:28 +1100 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Kris Kennaway In-Reply-To: <20031110033209.GA4897@xor.obsecurity.org> Message-ID: <20031110190237.N2387@gamplex.bde.org> References: <200311100311.hAA3B87q063999@repoman.freebsd.org> <20031110033209.GA4897@xor.obsecurity.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: cvs-src@FreeBSD.org cc: src-committers@FreeBSD.org cc: David Xu cc: cvs-all@FreeBSD.org Subject: Re: cvs commit: src/sys/sys signalvar.h X-BeenThere: cvs-all@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: CVS commit messages for the entire tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Nov 2003 08:27:51 -0000 On Sun, 9 Nov 2003, Kris Kennaway wrote: > On Sun, Nov 09, 2003 at 07:11:08PM -0800, David Xu wrote: > > davidxu 2003/11/09 19:11:08 PST > > > > FreeBSD src repository > > > > Modified files: > > sys/sys signalvar.h > > Log: > > If a thread masks all its signal, in cursig(), no signal will be exchanged > > with debugger, so testing P_TRACED in SIGPENDING is useless. This test also > > is the culprit which causes lots of 'failed to set signal flags properly for > > ast()' to be printed on console which is just a false complaint. > > Yay! This has been on my bug list for ages. Me too. See the appended mail which diagnosed the problem with P_TRACED and another with P_PPWAIT last March. Progress was stalled because no one replied. I rarely see the dignostic since I normally have it turned off (unconditionally compiled with more debugging info, but enabled by a flag that is turned off). Bruce >From bde@zeta.org.au Thu Mar 13 03:25:44 2003 +1100 Date: Thu, 13 Mar 2003 03:25:41 +1100 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Tim Robbins cc: current@FreeBSD.ORG Subject: Re: failed to set signal flags properly for ast() In-Reply-To: <20030312141804.A12375@dilbert.robbins.dropbear.id.au> Message-ID: <20030313023818.O450@gamplex.bde.org> References: <20030312141804.A12375@dilbert.robbins.dropbear.id.au> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Status: O X-Status: X-Keywords: X-UID: 7515 On Wed, 12 Mar 2003, Tim Robbins wrote: > Compile, run under gdb, then type "print test()" when the program receives > SIGABRT. Seems to work incorrectly on 4.7 too. > > #include > #include > > void > test(void) > { > > puts("hello"); > } > > int > main(int argc, char *argv[]) > { > > abort(); > exit(0); > } Thanks. At last it is possible to reproduce this bug :-). The bug seems to be that issignal() is quite broken. It gets called for masked signals in the P_TRACED case, but never does anything for masked signals, but at least the following things poing to a need for doing something for masked signals: - the special case for P_TRACED in SIGPENDING() - the incorrect behaviour of the above program in RELENG_4. I think it misbehaves in the same way under -current except in the INVARIANTS case the sanity check spews kernel printfs. - code in NetBSD's issignal() to do something in the (p->p_stat == SSTOP) case without even checking if there are any signals (masked or not). This bug seems to go back to at least FreeBSD-1 (Net/2). SIGPENDING() is also inconsistent with issignal() in the P_PPWAIT case. I think this just wastes time doing null calls to issignal(), and triggers the INVARIANTS check in the same way as the P_TRACED case (see below). This seems to go back to FreeBSD-1 too. SIGPENDING() is consistent with issignal() in the S_SIG case, but this may be wrong since S_SIG is similar to P_TRACED. The invariants check gets trigger as follows: - sigpending() is called correctly. - ast() clears the flags set by sigpending() and "handles" the signal using "while ((sig == cursig(td)) != 0) postsig()". But cursig() doesn't find any signals since all the pending ones are masked. - userret() checks that pending signals were handled. It finds unhandled masked ones and thinks they needed handling because P_TRACED is set. (IIRC, there is only a SIGTRAP pending to begin with, but attempting to control the process using ^C^Z gave masked SIGINTs and SIGSTOPs too). Appart from the diagnostic, the incorrect working in -current is to loop endlessly calling ast() and usrret(). ^C^Z doesn't stop it because they are masked. Bruce >From bde@zeta.org.au Fri Mar 14 06:46:29 2003 +1100 Date: Fri, 14 Mar 2003 06:46:27 +1100 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Tim Robbins cc: current@FreeBSD.ORG Subject: Re: failed to set signal flags properly for ast() In-Reply-To: <20030312141804.A12375@dilbert.robbins.dropbear.id.au> Message-ID: <20030314061240.L817@gamplex.bde.org> References: <20030312141804.A12375@dilbert.robbins.dropbear.id.au> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Status: O X-Status: X-Keywords: X-UID: 7526 On Wed, 12 Mar 2003, Tim Robbins wrote: > Compile, run under gdb, then type "print test()" when the program receives > SIGABRT. Seems to work incorrectly on 4.7 too. > > #include > #include > > void > test(void) > { > > puts("hello"); > } > > int > main(int argc, char *argv[]) > { > > abort(); > exit(0); > } Here's a simpler example: %%% #include #include #include int main(int argc, char *argv[]) { sigset_t mask, omask; volatile int i; sigfillset(&mask); sigprocmask(SIG_SETMASK, &mask, &omask); exit(0); } %%% Single stepping through this hangs at the end of the sigprocmask() and triggers the INVARIANTS check. This is because masking SIGTRAP fouls up trap handling. I first tried masking only SIGTRAP. This caused a SIGSEGV on return of sigprocmask(). Masking SIGSEGV as well stops gdb seeing any signals. abort() causes similar misbehaviour by masking almost all signals. gdb gets control for SIGABRT because SIGABRT is not masked, but "call test()" hangs because it generates a SIGTRAP but SIGTRAP is masked. The system states are approx. 10% user and 90% sys for the hang in both cases, so it seems that the misbehaviour is just the usual one for bogusly masking signals for restartable exceptions if such an exception occurs, and the bug is mainly in the sanity check (SIGPENDING()'s P_TRACED check is less than a pessimization). Bruce