Hey, debugging question. We're writing a Rust program that uses raw terminal input (ie. disables line-buffering), and we're seeing behavior that we think is attributable to the Rust std environment resetting the terminal modes on exit. Is that... a thing?
We would like to find where it's documented, if so, or failing that the source for it.
We could get our code working without worrying about that, but we really want to make sure we're attributing the behavior to the correct component.
We're making progress with writing a reduced test case; it's looking likely that this is attributable to the "nix" crate.
Well, we've got our test case... we're now reasonably sure something is actually installing a signal handler.
This is a weird one because the behavior we can't explain is actually the cleanup. We know exactly why our terminal is sometimes broken when we exit badly; what we can't explain is why it's sometimes *not* broken.
Exiting via Rust's panic!() facility does not get the cleanup behavior. Exiting normally *also* does not get it. That seems to rule out a Drop instance, we think...? We're new to Rust.
The only case where we can reliably reproduce the surprise cleanup is if we ^C out of our program.
You may well be asking why we care, and to that we can only say that we never gave up on our childish ideal of understanding what the computer is doing.
Okay. We prepared a second test case that avoids relying on the "nix" crate. It's either "libc" or "std" to blame.
The good news is that we figured out how to programmatically invoke the unwanted cleanup, and also how to override it. The bad news is that our approach shouldn't work and we still don't know why it does.
If we manually send an unhandled signal, causing our Rust program to terminate, the unwanted cleanup happens. We tried with both SIGABRT and SIGINT.
Calling the low-level signal() function, however, says that there wasn't a handler installed.
Installing our own handler does suppress the unwanted cleanup. Great. That's nice. LOL.
At this point the only thing we can think of is that maybe the Rust runtime is setting up one of glibc's non-POSIX exit handlers. The POSIX ones don't run when you exit due to an unhandled signal, but the glibc one... might?
We have no idea why anyone would do that.
So actually, we remembered one more way this might be the shell's fault. We're going to try a different way of invoking the process!
Earlier, we had tried to "fake" the exit code, but we had forgotten that the exit code, at a low level, contains more than just the part generated by userspace... it also says whether the process is terminated by a signal.
We've looked pretty hard in the relevant Rust source for any cleanup functionality like this, so we're now suspecting it's a bash feature.
We verified that it is indeed that code responsible, by trying our program as:
$ (cargo run; true)
You need the true there or bash decides it doesn't really need a subshell after all.
Before we resorted to reading the bash source, we first tried running our program from several other shells, including tcsh, zsh, and a couple others that we learned about from Wikipedia. It turns out all those shells had similar functionality.
zsh actually fixes up the terminal unconditionally, which... surely breaks the stty command, right?
Anyway, now that we know that this strange magic is not *Rust* magic, we can proceed with the obvious strategy to avoid it by installing our own handler. (That has been the obvious strategy for several hours now. :))
Shout-outs to @a_hoverbear and @sschinke, who were both instrumental in helping us through this.
We have no regrets. That was very educational.
Everybody reads the source code to a new programming language as they're learning it, right? ;)
we joked earlier that we were trying to get to the root of this out of idealism, and that's true and we stand by it, but also we had a practical reason, which is that the project we're writing is a shell and we really can't have it doing weird things around termination
• • •
Missing some Tweet in this thread? You can try to
force a refresh
So first off, let us talk about why we're doing this. We've been using Unix command lines for... a bit over 25 years at this point, we think. In all that time we've developed some opinions.
We don't expect this to change the world. We expect it to be a moderately useful tool. We're well-known enough at this point that it's quite possible people besides ourselves will use it, and if so, we'll be happy. We'll also be happy if we're the only ones who do.
We're live-tweeting PEPR20! After the break, this will be the thread head for the fourth block of talks ("session"), which will be the last one for the first day. #pepr20
"Product Privacy Journey: Towards a Product Centric Privacy Engineering Framework", by Igor Trindale Oliveira, is now starting.
Why a product-centric approach? Other possible focuses would be compliance, design, engineering, users... #pepr20
Okay! This will be the thread head for the third session of #pepr20, which will re-convene after the birds-of-a-feather breakout sessions, in about ten minutes.
We have a secret motive for tweeting this, it helps us pay attention. Our brain doesn't cling to things unless we're using *all* of our brain.
Okay, the theme of this next block of talks ("session") is design. So now we're on slack channel 3. #pepr20
Just to keep our tweets organized, this will be the thread topper for our live-tweet of session 2 of #pepr20, when the break is over.
Okay! We're back from break. The talk title went by very quickly, ... now there's a pause, hopefully the speaker will introduce themselves again. #pepr20
According to the schedule, this one should be "Building and Deploying a Privacy Preserving Data Analysis Platform", by Frederick Jansen. #pepr20
Okay! We will be live-tweeting #PEPR20, the USENIX conference on Privacy Engineering Practice and Respect. Feel free to mute that hashtag if you don't want to drown in tweets.
Just so people know, if you're a trans person working any sort of professional job and you're interested in advocating to your company about healthcare, we're happy to chat privately about what to ask for and how.
We were heavily involved in efforts around that during our time at Google, and there's a lot of transferable knowledge that applies to any company.
Belatedly, we realized that because we DO have that highly detailed knowledge on this topic, we should directly talk about Discord's thing.