* Signal left blocked after signal handler.
@ 2003-11-26 17:39 Bruce Perens
2003-11-26 17:55 ` Linus Torvalds
2003-11-27 9:20 ` Herbert Xu
0 siblings, 2 replies; 14+ messages in thread
From: Bruce Perens @ 2003-11-26 17:39 UTC (permalink / raw)
To: linux-kernel; +Cc: torvalds
Hi,
A signal should be blocked while its signal handler is executing, and
then unblocked when the handler returns - unless SA_NOMASK is set.
-test9 and -test10 leave the signal _blocked_forever_.
This causes the build-time confidence test for Electric Fence to break,
and no doubt lots of other code.
If SA_NOMASK is set, the signal is not blocked.
Test program attached below.
Thanks
Bruce
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
static sigjmp_buf sjbuf;
static int sig = SIGINT;
static void
handler(int i)
{
struct sigaction act;
memset((void *)&act, 0, sizeof(act));
act.sa_handler = SIG_DFL;
fprintf(stderr, "Signal handler hit!\n");
fflush(stderr);
sigaction(sig, &act, 0);
siglongjmp(sjbuf, 1);
}
static void
invoke_signal()
{
struct sigaction act;
memset((void *)&act, 0, sizeof(act));
act.sa_handler = handler;
/* act.sa_flags = SA_NOMASK; */
if ( sigsetjmp(sjbuf, 0) == 0 ) {
sigaction(sig, &act, 0);
fprintf(stderr, "Sending signal... ");
fflush(stderr);
kill(getpid(), sig);
fprintf(stderr, "Huh? Nothing happened. Signal was left blocked.\n");
}
}
int
main(int argc, char * * argv)
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
invoke_signal();
invoke_signal();
fprintf(stderr, "Unblocking signal... ");
if ( sigsetjmp(sjbuf, 0) == 0 ) {
sigprocmask(SIG_UNBLOCK, &set, 0);
}
return 0;
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Signal left blocked after signal handler.
2003-11-26 17:39 Signal left blocked after signal handler Bruce Perens
@ 2003-11-26 17:55 ` Linus Torvalds
[not found] ` <3FC4ED5F.4090901@perens.com>
2003-11-27 9:20 ` Herbert Xu
1 sibling, 1 reply; 14+ messages in thread
From: Linus Torvalds @ 2003-11-26 17:55 UTC (permalink / raw)
To: Bruce Perens, Ulrich Drepper; +Cc: Kernel Mailing List
[ Uli added to participants ]
On Wed, 26 Nov 2003, Bruce Perens wrote:
>
> A signal should be blocked while its signal handler is executing, and
> then unblocked when the handler returns - unless SA_NOMASK is set.
>
> -test9 and -test10 leave the signal _blocked_forever_.
>From what I can tell, this is a glibc bug. Do an "strace" on the program,
and see how "siglongjmp()" doesn't appear to do any system calls at all.
It's up to siglongjmp() to restore the signal mask that it saved on
sigsetjmp().
What library version are you using (but yes, I see the same thing with
"Fedora Core 1").
In fact, with strace I don't even see where the signal mask would be
_saved_ in sigsetjmp. So as far as I can tell, this just cannot work.
Linus
--- rest of email saved for Uli ---
>
> This causes the build-time confidence test for Electric Fence to break,
> and no doubt lots of other code.
>
> If SA_NOMASK is set, the signal is not blocked.
>
> Test program attached below.
>
> Thanks
>
> Bruce
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <signal.h>
> #include <setjmp.h>
>
> static sigjmp_buf sjbuf;
> static int sig = SIGINT;
>
> static void
> handler(int i)
> {
> struct sigaction act;
>
> memset((void *)&act, 0, sizeof(act));
> act.sa_handler = SIG_DFL;
>
> fprintf(stderr, "Signal handler hit!\n");
> fflush(stderr);
> sigaction(sig, &act, 0);
> siglongjmp(sjbuf, 1);
>
> }
>
> static void
> invoke_signal()
> {
> struct sigaction act;
>
> memset((void *)&act, 0, sizeof(act));
> act.sa_handler = handler;
>
> /* act.sa_flags = SA_NOMASK; */
>
> if ( sigsetjmp(sjbuf, 0) == 0 ) {
> sigaction(sig, &act, 0);
> fprintf(stderr, "Sending signal... ");
> fflush(stderr);
> kill(getpid(), sig);
> fprintf(stderr, "Huh? Nothing happened. Signal was left blocked.\n");
> }
> }
>
> int
> main(int argc, char * * argv)
> {
> sigset_t set;
>
> sigemptyset(&set);
> sigaddset(&set, sig);
>
> invoke_signal();
> invoke_signal();
> fprintf(stderr, "Unblocking signal... ");
> if ( sigsetjmp(sjbuf, 0) == 0 ) {
> sigprocmask(SIG_UNBLOCK, &set, 0);
> }
>
> return 0;
> }
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Signal left blocked after signal handler.
2003-11-26 17:39 Signal left blocked after signal handler Bruce Perens
2003-11-26 17:55 ` Linus Torvalds
@ 2003-11-27 9:20 ` Herbert Xu
1 sibling, 0 replies; 14+ messages in thread
From: Herbert Xu @ 2003-11-27 9:20 UTC (permalink / raw)
To: Bruce Perens, linux-kernel
Bruce Perens <bruce@perens.com> wrote:
>
> Test program attached below.
I don't know about your other problems, but your code is buggy.
> if ( sigsetjmp(sjbuf, 0) == 0 ) {
For sigsetjmp to be useful, you need to call it with a nonzero
value in the second argument.
--
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Never mind. Re: Signal left blocked after signal handler.
@ 2003-11-26 21:53 Albert Cahalan
2003-11-27 9:11 ` Ingo Oeser
0 siblings, 1 reply; 14+ messages in thread
From: Albert Cahalan @ 2003-11-26 21:53 UTC (permalink / raw)
To: linux-kernel mailing list; +Cc: bruce, Linus Torvalds
> One difference in 2.4.x and 2.6.x is the signal blocking
> wrt blocked signals that are _forced_ (ie anything that
> is thread-synchronous, like a SIGSEGV/SIGTRAP/SIGBUS that
> happens as a result of a fault):
>
> - in 2.4.x they will just punch through the block
> - in 2.6.x they will refuse to punch through a blocked
> signal, but since they can't be delivered they will
> cause the process to be killed.
...
> and in 2.4.x this will cause infinte SIGSEGV's (well,
> they'll be caught by the stack size eventually, but you
> see the problem: do a "strace" to see what's going on).
> In 2.6.x the second SIGSEGV will just kill the program
> immediately.
How about making the process sleep in a killable state?
This is as if the blocking was obeyed, but doesn't
burn CPU time. Only a debugger should be able to
tell the difference.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Never mind. Re: Signal left blocked after signal handler.
2003-11-26 21:53 Never mind. " Albert Cahalan
@ 2003-11-27 9:11 ` Ingo Oeser
2003-11-27 15:45 ` Albert Cahalan
0 siblings, 1 reply; 14+ messages in thread
From: Ingo Oeser @ 2003-11-27 9:11 UTC (permalink / raw)
To: Albert Cahalan; +Cc: bruce, Linus Torvalds, linux-kernel mailing list
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Wednesday 26 November 2003 22:53, Albert Cahalan wrote:
[2.4 vs. 2.6 wrt. thread synchronous signals]
> How about making the process sleep in a killable state?
>
> This is as if the blocking was obeyed, but doesn't
> burn CPU time. Only a debugger should be able to
> tell the difference.
This has 2 problems:
1) Servers and PID files or servers and simple monitoring software.
2) Processes spawned from init, which will not respawn.
Regards
Ingo Oeser
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE/xb/mU56oYWuOrkARAmNaAKCL1uojbOpMtMdSvAl6B9rBW51CTgCgypP8
NlbaIac25oefxcHL9WlzxyE=
=h6UI
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Never mind. Re: Signal left blocked after signal handler.
2003-11-27 9:11 ` Ingo Oeser
@ 2003-11-27 15:45 ` Albert Cahalan
2003-11-27 17:26 ` Jörn Engel
0 siblings, 1 reply; 14+ messages in thread
From: Albert Cahalan @ 2003-11-27 15:45 UTC (permalink / raw)
To: Ingo Oeser; +Cc: bruce, Linus Torvalds, linux-kernel mailing list
On Thu, 2003-11-27 at 04:11, Ingo Oeser wrote:
> On Wednesday 26 November 2003 22:53, Albert Cahalan wrote:
> [2.4 vs. 2.6 wrt. thread synchronous signals]
> > How about making the process sleep in a killable state?
> >
> > This is as if the blocking was obeyed, but doesn't
> > burn CPU time. Only a debugger should be able to
> > tell the difference.
>
> This has 2 problems:
>
> 1) Servers and PID files or servers and simple monitoring software.
> 2) Processes spawned from init, which will not respawn.
It has benefits:
1. Continuous respawning is no good.
2. If the processes sleeps, you can attach a debugger.
The obviously correct behavior is to go back into
user space, likely to take the signal again. The only
thing wrong with this is that it eats CPU time.
So _pretend_ to do that. Have the process sleep,
ideally with an "R" state as seen in /proc, and maybe
even go back to the crazy loop if someone attaches a
debugger.
The crazy loop is most correct though. It's what the
user asked for. It perfectly handles the case of a
repeating SIGFPE (blocked) followed by some other
thread unmapping a page of instructions or data that
turns the SIGFPE into a SIGSEGV.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Never mind. Re: Signal left blocked after signal handler.
2003-11-27 15:45 ` Albert Cahalan
@ 2003-11-27 17:26 ` Jörn Engel
0 siblings, 0 replies; 14+ messages in thread
From: Jörn Engel @ 2003-11-27 17:26 UTC (permalink / raw)
To: Albert Cahalan
Cc: Ingo Oeser, bruce, Linus Torvalds, linux-kernel mailing list
On Thu, 27 November 2003 10:45:39 -0500, Albert Cahalan wrote:
>
> It has benefits:
>
> 1. Continuous respawning is no good.
But trivial to notice. :)
> 2. If the processes sleeps, you can attach a debugger.
If aunt Tilly has a core dump, her son can extract it and send it to
some developer. No need for you to drive over to aunt Tilly.
> The obviously correct behavior is to go back into
> user space, likely to take the signal again. The only
> thing wrong with this is that it eats CPU time.
> So _pretend_ to do that. Have the process sleep,
> ideally with an "R" state as seen in /proc, and maybe
> even go back to the crazy loop if someone attaches a
> debugger.
>
> The crazy loop is most correct though. It's what the
> user asked for. It perfectly handles the case of a
> repeating SIGFPE (blocked) followed by some other
> thread unmapping a page of instructions or data that
> turns the SIGFPE into a SIGSEGV.
"It just what you asked for, but not what you wanted."
I am a firm non-believer in the trust-the-programmer paradigm. How
many people actually intend to do NULL-pointer dereferences, etc? To
make this possible "if you really really want to" is ok, but at least
make the bad behaviour hard to trigger by accident.
What Linux did in 2.5.7x is not exacly what I would have done, but it
makes it hard to do the Wrong Thing (tm) by accident, while allowing
it for those who really want it. Good enough for most users.
Jörn
--
Those who come seeking peace without a treaty are plotting.
-- Sun Tzu
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2003-11-27 17:27 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-26 17:39 Signal left blocked after signal handler Bruce Perens
2003-11-26 17:55 ` Linus Torvalds
[not found] ` <3FC4ED5F.4090901@perens.com>
2003-11-26 18:21 ` Linus Torvalds
[not found] ` <3FC4EF24.9040307@perens.com>
2003-11-26 18:34 ` Linus Torvalds
[not found] ` <3FC4F248.8060307@perens.com>
2003-11-26 18:45 ` Never mind. " Linus Torvalds
2003-11-26 19:04 ` Bruce Perens
2003-11-26 19:14 ` Linus Torvalds
2003-11-26 19:34 ` Posix says "undefined". " Bruce Perens
2003-11-26 19:52 ` Never mind. " Jamie Lokier
2003-11-27 9:20 ` Herbert Xu
2003-11-26 21:53 Never mind. " Albert Cahalan
2003-11-27 9:11 ` Ingo Oeser
2003-11-27 15:45 ` Albert Cahalan
2003-11-27 17:26 ` Jörn Engel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).