Reading compressed character maps and gzip EPIPE issues.

Carlos O'Donell carlos@redhat.com
Sun Nov 24 04:46:00 GMT 2019


On 11/23/19 3:24 PM, Florian Weimer wrote:
> * Carlos O'Donell:
> 
>> Current localedef uses posix_spawnp, which uses vfork, which blocks
>> all signals while it starts the child. Should we be setting the
>> signal mask appropriately for posix_spawnp so SIGPIPE can reach
>> gzip? Is that what we're getting at?
> 
> I'm pretty sure that posix_spawnp does not block signals in this way.
> If it does, it would be a bug.  strace shows this (with current
> master):

Sorry, I only meant to say that we do block signals in the parent
while we start the child, but then you're right we promptly unblock
in the child as required. I hasn't gone through all of __spawni_child
yet.

glibc/sysdeps/unix/sysv/linux/spawni.c (__spawnix):
372   __libc_signal_block_all (&args.oldmask);
...
382   new_pid = CLONE (__spawni_child, STACK (stack, stack_size), stack_size,
383                    CLONE_VM | CLONE_VFORK | SIGCHLD, &args);
414   __libc_signal_restore_set (&args.oldmask);

glibc/sysdeps/unix/sysv/linux/spawni.c (__spawni_child):
136   sigset_t hset;
137   __sigprocmask (SIG_BLOCK, 0, &hset);
...
287   /* Set the initial signal mask of the child if POSIX_SPAWN_SETSIGMASK
288      is set, otherwise restore the previous one.  */
289   __sigprocmask (SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
290                  ? &attr->__ss : &args->oldmask, 0);
291 
292   args->exec (args->file, args->argv, args->envp);
293 

> 30925 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
> 30925 execve("/usr/local/bin/gzip", ["gzip", "-d", "-c"], 0x7ffe16fec8f8 /* 47 vars */) = -1 ENOENT (No such file or directory)
> 30925 execve("/usr/bin/gzip", ["gzip", "-d", "-c"], 0x7ffe16fec8f8 /* 47 vars */) = -1 ENOENT (No such file or directory)
> 30925 execve("/bin/gzip", ["gzip", "-d", "-c"], 0x7ffe16fec8f8 /* 47 vars */ <unfinished ...>
> 
> This suggests to me that posix_spawnp properly restores the signal
> mask.  I think you need to investigate why your environment runs
> localedef with SIGPIPE blocked.
 
I have strace logs for the runs (which only happened once in a particular shell):

1574310173.012834 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
1574310173.012851 execve("/usr/lib64/qt-3.3/bin/gzip", ["gzip", "-cdq", "-"], 0x7ffc844ee480 /* 78 vars */) = -1 ENOENT (No such file or directory)
1574310173.012879 execve("/usr/share/Modules/bin/gzip", ["gzip", "-cdq", "-"], 0x7ffc844ee480 /* 78 vars */) = -1 ENOENT (No such file or directory)
1574310173.012902 execve("/usr/local/bin/gzip", ["gzip", "-cdq", "-"], 0x7ffc844ee480 /* 78 vars */) = -1 ENOENT (No such file or directory)
1574310173.012925 execve("/usr/bin/gzip", ["gzip", "-cdq", "-"], 0x7ffc844ee480 /* 78 vars */) = 0
...
1574310173.014284 write(1, "<code_set_name> EUC-JP-MS\n<comme"..., 32768) = 32768
1574310173.014466 write(1, "   CYRILLIC SMALL LETTER DE\n<U04"..., 32768) = -1 EPIPE (Broken pipe)
1574310173.014498 --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=10480, si_uid=1000} ---
1574310173.014521 write(2, "\ngzip: ", 7) = 7
1574310173.014619 write(2, "stdout: Broken pipe\n", 20) = 20
1574310173.014658 rt_sigprocmask(SIG_BLOCK, [HUP INT TERM XCPU], [], 8) = 0
1574310173.014689 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
1574310173.014717 exit_group(1)         = ?
1574310173.014805 +++ exited with 1 +++

So SIGPIPE is delivered, but gzip still writes the error message?
Why isn't gzip killed by the signal?

-- 
Cheers,
Carlos.



More information about the Libc-alpha mailing list