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