This is the mail archive of the
libc-alpha@sourceware.cygnus.com
mailing list for the glibc project.
Re: [sbachman@saveware.com] libc/1534: When a program execl()'s ina signal function, the new program no longer responds to any signals set bythe user.
- To: Andreas Jaeger <aj at suse dot de>
- Subject: Re: [sbachman@saveware.com] libc/1534: When a program execl()'s ina signal function, the new program no longer responds to any signals set bythe user.
- From: Kaz Kylheku <kaz at ashi dot footprints dot net>
- Date: Fri, 14 Jan 2000 13:39:49 -0800 (PST)
- cc: libc-alpha Mailinglist <libc-alpha at sourceware dot cygnus dot com>, sbachman at saveware dot com
On 14 Jan 2000, Andreas Jaeger wrote:
> Hi glibc developers & testers,
>
> We've received the appended bug report. For me this looks like a bug
> in the kernel. AFAIK Posix explicitly mentions execl as a function
> which is allowed to be called from a signal handler (printf is not
> signal safe but I don't think that this is the problem here).
>
> What do you think? Should this be forwarded to linux-kernel?
Hmm. New program no longer responds to any signals, eh? That's a bit vague,
it requires more investigation. Does any signals include SIGKILL and SIGQUIT?
I would guess not.
This blurb from the Single Unix Spec might also be useful
The new process also inherits at least the following attributes from the
calling process image:
nice value (see nice())
semadj values (see semop())
process ID
parent process ID
process group ID
session membership
real user ID
real group ID
supplementary group IDs
time left until an alarm clock signal (see alarm())
current working directory
root directory
file mode creation mask (see umask())
file size limit (see ulimit())
*** process signal mask (see sigprocmask())
pending signal (see sigpending())
tms_utime, tms_stime, tms_cutime, and tms_cstime (see times())
resource limits
controlling terminal
interval timers
Asterisks mine next to process signal mask.
Let's look at the program.
> #include <signal.h>
> #include <stdio.h>
> #include <unistd.h>
>
> void foo2( int sig )
> { printf("Foo 2 you too at %d\n",sig); }
>
> void foo( int sig )
> {
> printf("I got signal %d\n", sig);
> execl("./testd","./testd",(char *) 0);
> }
>
> int main()
> {
> struct sigaction newaction;
>
> newaction.sa_handler = foo;
> newaction.sa_flags = 0;
This is poor programming. Note that newaction has automatic storage. Yet it is
not fully initialized. Only the members sa_handler and sa_flags are
initialized. The use of uninitialized objects results in undefined behavior.
In particular, the contents of sa_mask are anyone's guess.
When the signal handler goes off, therefore, we have no clue what
signals are in the process signal mask. We know that the delivered signal
is masked, but there may be other additional signals that are masked.
Now when the new process image is launched with execl inside the
signal handler (which, by the way, is a very poor idea that wouldn't
occur to me in the wildest dreams!) the new process image inherits
the existing process signal mask. So it may have some signals blocked.
We know that the delivered signal that was handled is blocked for sure.
That would explain why the new process is not responding to some, or possibly
all blockable/catchable signals.
My suggestion: correct the horrible bugs in the program, and clear the mask of
blocked signals by calling sigprocmask appropriately prior to the execl and see
whether the problem goes away.