Document safety of fork() and fix tests#695
Conversation
|
|
||
| // Safe: Child only calls `_exit`, which is signal-safe | ||
| let pid = unsafe { fork() }; | ||
| match pid { |
There was a problem hiding this comment.
Let's get rid of the pid variable completely here for consistency with other tests and since it isn't used anywhere else.
| /// | ||
| /// # Safety | ||
| /// | ||
| /// In a multithreaded program, only [async-signal-safe] functions may be called |
There was a problem hiding this comment.
Your comments talk about libc::exit and libc::pause being safe to use here. Let's explicitly list those here. We should also state that std::process:exit is not safe.
There was a problem hiding this comment.
libc::exit actually isn't safe, only _exit is
There was a problem hiding this comment.
Sorry, that's what I meant. We should document a few of the safe and unsafe things for reference. The big thing about this is that how would the user figure out what is safe or not. I don't know if we have any guidance on that end, however.
asomers
left a comment
There was a problem hiding this comment.
I like all of the changes that you've made to the tests. But I still think it's premature to mark fork as unsafe. It's not that I think fork is safe; it's that I think consistency between nix and libstd is more important.
Nobody has yet come up with a POC that violates Rust's memory safety rules by forking. Until that happens, I don't think libstd is going to change.
| let (reader, writer) = pipe().unwrap(); | ||
|
|
||
| match fork().unwrap() { | ||
| // Safe: Child calls `exit`, `dup` and the provided `exec*` family function. |
There was a problem hiding this comment.
If you're going to list them all, you should add close
And this is a very bad thing IMO. Maybe it's hard to come up with a POC on the currently supported configurations, but what about other allocator implementations, other libcs, other operating systems, other architectures where this is a more serious issue? Even if those aren't supported by Rust today, even if those configurations don't even exist today - the fact that POSIX says "don't do this it's unsafe" should be more than enough of a reason to proceed with extreme caution. A language that aims to guarantee memory safety shouldn't do things like this. |
|
POSIX says it's "unsafe", but the libstd guys say it's not |
|
Yeah, seems like POSIX leaves the meaning of "safe" completely undefined. Depending on that, |
|
As an aside, from the docs of
I would be very surprised if "the behaviour is undefined" means something different than UB in C in this context, and the child handler is basically just code that is executed by the child after a fork, so there isn't much of a difference to what we're dealing with. (UB is strictly worse than memory unsafety, after all) |
|
I don't want to argue with you about the safety of |
|
I'd like to echo what @asomers says here. Rust has a pretty narrow definition of "unsafe" and whatever |
|
PR #566 just added a new |
Some tests were invoking non-async-signal-safe functions from the child process after a `fork`. Since they might be invoked in parallel, this could lead to problems.
Note that ptrace isn't documented as signal-safe, but it's supposed to just be a light syscall wrapper, so it should be fine.
fork() unsafe and fix testsfork() and fix tests
|
Thanks for the PR @jonas-schievink . Looks like we can sneak this one into 0.9.0 bors r+ |
Build succeeded |
Some tests were invoking non-async-signal-safe functions from the child
process after a
fork. Since they might be invoked in parallel, thiscould lead to problems.
cc #586