-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Follow-up changes for blocking unamed_socket #4099
Changes from 1 commit
8c044ec
e252bc6
a0b952e
c2a3b7b
6b513fc
67af109
21a6a90
7f844ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
//@ignore-target: windows # No libc socketpair on Windows | ||
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / coverage reportexpexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)expexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)expexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (windows-latest, i686-pc-windows-msvc)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (windows-latest, i686-pc-windows-msvc)Unmatched diagnostics
|
||
//@compile-flags: -Zmiri-preemption-rate=0 | ||
|
||
use std::thread; | ||
|
||
fn main() { | ||
let mut fds = [-1, -1]; | ||
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; | ||
assert_eq!(res, 0); | ||
let arr1: [u8; 212992] = [1; 212992]; | ||
// Exhaust the space in the buffer so the subsequent write will block. | ||
let res = unsafe { libc::write(fds[0], arr1.as_ptr() as *const libc::c_void, 212992) }; | ||
assert_eq!(res, 212992); | ||
let thread1 = thread::spawn(move || { | ||
let data = "abc".as_bytes().as_ptr(); | ||
// The write below will be blocked because the buffer is already full. | ||
let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; | ||
Check failure on line 17 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics
Check failure on line 17 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics
Check failure on line 17 in tests/fail-dep/libc/socketpair_closed_while_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics
|
||
assert_eq!(res, 3); | ||
}); | ||
let thread2 = thread::spawn(move || { | ||
// Close the socketpair fd while thread1 is blocking on it. | ||
assert_eq!(unsafe { libc::close(fds[0]) }, 0); | ||
// Unblock thread1 by freeing up some space. | ||
let mut buf: [u8; 3] = [0; 3]; | ||
let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; | ||
assert_eq!(res, 3); | ||
assert_eq!(buf, [1, 1, 1]); | ||
}); | ||
thread1.join().unwrap(); | ||
thread2.join().unwrap(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
error: deadlock: the evaluated program deadlocked | ||
| | ||
= note: the evaluated program deadlocked | ||
= note: (no span available) | ||
= note: BACKTRACE on thread `unnamed-ID`: | ||
|
||
error: deadlock: the evaluated program deadlocked | ||
--> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC | ||
| | ||
LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ||
| ^ the evaluated program deadlocked | ||
| | ||
= note: BACKTRACE: | ||
= note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC | ||
= note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC | ||
= note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC | ||
note: inside `main` | ||
--> tests/fail-dep/libc/socketpair_closed_while_blocking.rs:LL:CC | ||
| | ||
LL | thread1.join().unwrap(); | ||
| ^^^^^^^^^^^^^^ | ||
|
||
error: deadlock: the evaluated program deadlocked | ||
--> tests/fail-dep/libc/socketpair_closed_while_blocking.rs:LL:CC | ||
| | ||
LL | let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; | ||
| ^ the evaluated program deadlocked | ||
| | ||
= note: BACKTRACE on thread `unnamed-ID`: | ||
= note: inside closure at tests/fail-dep/libc/socketpair_closed_while_blocking.rs:LL:CC | ||
|
||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | ||
|
||
error: aborting due to 3 previous errors | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently the diagnostic already shows deadlock on
write
because we wake up the blockedwrite
thread only if the fd blocked onwrite
is not closed:Relevant code snippet:
miri/src/shims/unix/unnamed_socket.rs
Lines 304 to 314 in 3eea5b8
This is acceptable, but I wanted to try if it is possible to let the diagnostic point to
close
and tell the user that "this thread never wakes up because of theclose
here".EDIT: On other note, this also means that
throw_unsupported
inanonsocket_write
is unreachable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's still an odd
throw_unsupported
in that logic that we should get rid of. Either it is unreachable and should become an assert, or else you can adjust the test to reach it. (I think it is reachable.)Improving the diagnostics is nice, but getting rid of that
throw_unsupported
is the more important part IMO.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking a little bit more, I am inclined to think that the unsupported for
unnamed_socket read/write
might be both unreachable, so I might remove both. But I will add test(s) to reconfirm it.