This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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.


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]