This is the mail archive of the libc-hacker@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: sleep ignore sigchld


> 
> I appologize for taking so long to get back to you.
> Here's a simpler program that demonstrates the unexpected
> behaviour I get from sleep() and SIGCHLD.
> I've included a sample run and "strace" as you requested.
> It's not necessarily a bug ¯-
>  ¯ It's just that on other Unixes sleep() will not be
>  interrupted by receiving SIGCHLD when SIGCHLD has been set to
>  SIG_IGN.
> On RedHat 5.1 (linux 2.0.34) it seems that sleep IS interrupted
>  even when the signal is ignored.
> 
> [adrian@india adrian]$ cat trash2.c
> #include <stdio.h>
> #include <signal.h>
> 
> int main(int argc, char * argv[]) {
>   int i_slept;
>   signal(SIGCHLD, SIG_IGN);
>   if(fork() != 0) {
>     i_slept = sleep(10);
>     printf("Parent woke up after %d (should be 10)\n",
>            10 - i_slept
>      );
>   } else {
>     sleep(3);
>     _exit(0);
>   }
> }
> [adrian@india adrian]$ 
> [adrian@india adrian]$ 
> [adrian@india adrian]$ cc trash2.c && ./a.out
> Parent woke up after 3 (should be 10)
> [adrian@india adrian]$ 
> [adrian@india adrian]$ 
> [adrian@india adrian]$ strace ./a.out
> execve("./a.out", ["./a.out"], [/* 22 vars */]) = 0
> brk(0)                                  = 0x80496d4
> open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
> open("/etc/ld.so.cache", O_RDONLY)      = 3
> fstat(3, {st_mode=0, st_size=0, ...})   = 0
> mmap(0, 14284, PROT_READ, MAP_PRIVATE, 3, 0) = 0x4000b000
> close(3)                                = 0
> open("/lib/libc.so.6", O_RDONLY)        = 3
> mmap(0, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0x4000f000
> munmap(0x4000f000, 4096)                = 0
> mmap(0, 670420, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x4000f000
> mprotect(0x400a0000, 76500, PROT_NONE)  = 0
> mmap(0x400a0000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x90000) = 0x400a0000
> mmap(0x400a7000, 47828, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x400a7000
> close(3)                                = 0
> personality(PER_LINUX)                  = 0
> getpid()                                = 1375
> sigaction(SIGCHLD, {SIG_IGN}, {SIG_DFL}) = 0
> fork()                                  = 1376
> nanosleep(0xbffffd58, 0xbffffd58, 0x400a5ddc, 0x1, 0x80484bc) = -1 EINTR (Interrupted system call)
> --- SIGCHLD (Child exited) ---

That is a kernel bug. SIGCHLD is a special one. Usually it cannot
be ignored. The older libc. Solaris and Hp-UX use alarm/pause to
implement sleep. It goes back to sleep when SIGCHLD arrives if
SIGCHLD is ignored. The problem is glibc uses nanosleep to implement
sleep. The bug is in nanosleep in kernel. I don't think nanosleep
should wake up when SIGCHLD arrives if SIGCHLD is ignored. We have
to treat SIGCHLD specially for nanosleep.


H.J.


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