mirror of
https://github.com/asciinema/asciinema.git
synced 2026-04-25 16:05:52 +03:00
[GH-ISSUE #369] “Broken pipe” errors when piping inside asciinema #848
Labels
No labels
bug
compatibility
feature request
fit for beginners
help wanted
hosting
idea
improvement
packaging
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/asciinema#848
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @klmr on GitHub (Sep 4, 2019).
Original GitHub issue: https://github.com/asciinema/asciinema/issues/369
I’ve noticed the following behaviour in asciinema 2.0.2:
This happens whenever the first program in a pipeline receives a SIGPIPE from the second command, and the data to be piped exceeds a certain length (in my terminal, in the above, using
{1..20000}is not reproducibly enough to trigger the behaviour, but it sometimes is). The behaviour is the same for a wide range of programs, not justcat.(macOS 10.14.6, bash 4.4.19 with iTerm 3.3.2 as well as Terminal.app)
@karlkfi commented on GitHub (Feb 2, 2021):
I see this pretty repeatably when reading from urandom:
@ku1ik commented on GitHub (May 17, 2022):
I cannot reproduce the problem on either Linux or macOS anymore. I believe this got fixed in either 2.1.0 or 2.2.0. Feel free to re-open if it still doesn't work for you. Thx!
@klmr commented on GitHub (May 17, 2022):
Unfortunately I am still able to reproduce this issue with asciinema 2.2.0 — on both macOS 10.14.6 as well as Ubuntu 18.04.
Just to check whether something in my shell configuration might be interfering, I even launched it with a clean environment, but the issue persists:
(I can’t reopen the issue, only contributors can.)
@ku1ik commented on GitHub (May 17, 2022):
Now I know why I couldn't reproduce. My default shell is fish and I was launching bash from within started recording session (which was running fish in the first place).
For me it was roughly an equivalent of:
The above doesn't break the pipe.
If your default shell is bash then in your case it's an equivalent of:
In this case I see the broken pipe error. Same for the
SUFFIX=...expression @karlkfi had trouble with.I'm not sure yet what's going on but I suspect something related to signal handling we have for the top level process (direct child of asciinema).
@Low-power commented on GitHub (Oct 18, 2023):
I can reproduce this issue on FreeBSD with latest commit (
e4fb2d6)@Low-power commented on GitHub (Oct 18, 2023):
The simplest test case I came up is:
This command line would normally produce no output.
Some truss(1) logs
Outside asciinema:
Inside asciinema:
Truss(1)ing asciinema all together:
Looks like somehow either Python or asciinema (PID 91551) ignored
SIGPIPE, then fork-exec'ed bash(1) (PID 92093) without restoring the signal action.@Low-power commented on GitHub (Oct 18, 2023):
My previous testings are done on a FreeBSD 11 OS with Python 3.6.
Now I also tested on FreeBSD 12 with Python 3.7 and 3.8, which both behaved exactly same (both ignored
SIGPIPE).Trying to break sigaction(2) in GDB to findout where it was get called:
Well, I guess
SIGPIPEwas ignored during the early initialization of Python. May be asciinema can workaround this Python bug by restoring this signal action toSIG_DFLbefore running user's command.@ku1ik commented on GitHub (Oct 21, 2023):
Great sleuthing @Low-power 👏 This is very interesting. Indeed
yes | truedoes it, as well asyes | head(which I've been testing with mostly).So, funny thing... I recreated the core part of the
pty.pyin Rust (see heregithub.com/asciinema/asciinema@909a496154/src/pty.rs), and the bug can be observed there too. Therefore, maybe what Python does during its initialization doesn't matter here? 🤔@Low-power commented on GitHub (Oct 22, 2023):
So... I implemented a very simple pseudo terminal testing program in C# (https://gist.github.com/Low-power/3637796bb0e8df298d3ff1c47e4ff2ea/), and experienced the same hehavior when running it in Mono.
Because I have the full source code of Mono on hand, I took a quick search for its handling of
SIGPIPE; sure enough it has ignored this signal on starts up (Mono source filemono/mini/mini-posix.c`):And this is the only place where
SIGPIPEappeared in the Mono VM source directory, as found by grep(1).I think most of the script interpreters and virtual machines ignore this signal without ever restore it.
@ku1ik commented on GitHub (Oct 22, 2023):
I've tested #578 with following commands:
cat large-file | headSUFFIX=$(< /dev/urandom tr -dc '[:digit:]' | head -c4)yes | trueyes | headWith the patch it seems to work without any errors.
@ku1ik commented on GitHub (Oct 22, 2023):
Yeah, I believe it goes like this: if parent process ignores SIGPIPE then child will by default ignore it. If parent uses custom handler for SIGPIPE then child will have it set to SIG_DFL. Or maybe it's always ignored by default as by your Mono example. Either way, #578 should do the trick.
@Low-power commented on GitHub (Oct 22, 2023):
Custom signal handlers will be reset to
SIG_DFLwhen exec a new program, whileSIG_IGNwill remain across exec; it is stated by POSIX (https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html).@ku1ik commented on GitHub (Oct 22, 2023):
There we have it. So I suppose we can merge #578, right?
@Low-power commented on GitHub (Oct 23, 2023):
Yes, I think that's a right thing to do.
@ku1ik commented on GitHub (Oct 23, 2023):
This has been fixed in v2.4.0: https://github.com/asciinema/asciinema/releases/tag/v2.4.0
@klmr commented on GitHub (Oct 23, 2023):
I just want to say, awesome job! It’s been a pleasure to watch this being solved step by step. Thanks to everyone who contributed to fixing this.