Closed jjpe closed 6 years ago
I'm reluctant to adding a Unknown
variant to zmq::Error
, as you suggest, as that would penalize all uses thereof, turning it from a C-like enum to a full-blown sum type. The default, panic case should not be reached, as you note yourself -- we should get to the bottom of why the match apparently misbehaves on OS X.
Ok I'm all for fixing this issue at its root.
Do you perhaps have any ideas on where we can start?
Because I'm not sure what exactly even goes wrong to be honest i.e. why it looks like on the one hand rustc sees EINTR
and 4
as equal, yet on the other hand the system does not.
There hasn't been a lot of progress here, but at the same time my project is not too far away from a 1.0.0 moment, at which point I'd like to push the rust components to crates.io.
In order to do that however, all the dependencies of my crates also need to live on crates.io, the Rust deployment mechanism in Cargo verifies this.
Which poses a conundrum: How can I release while this issue (which has effectively caused me to fork this project and thus introduce an unstable dependency as far as crates.io is concerned) is still unresolved?
The only 2 things I can think of are:
@jjpe: Issue #191 looks similiar, and is apparently fixed by commit 752765b2, contained in the (very recent) 0.8.2 release. Based on the code posted in that issue, I've constructed the following minimal test case:
extern crate zmq;
extern crate libc;
extern "C" fn s_signal_handler(_: i32) {
}
fn main() {
let ctx = zmq::Context::new();
unsafe {
libc::signal(2, s_signal_handler as libc::size_t);
}
let pull_socket = ctx.socket(zmq::PULL).unwrap();
let _ = pull_socket.recv_msg(0).unwrap();
}
If I start the above program from the command line on a Debian amd64 box, and hit Ctrl+C, I get as expected:
^Cthread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Interrupted system call', /checkout/src/libcore/result.rs:860:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Can you verify that the above sample code is still broken using v0.8.2?
Just tested against 0.8.2
.
As far as I can see, it all works properly now, both in your snippet and in my own project. Thanks for the fix!
I get this problem using v0.9, but only when I build a release: cargo build --release:
thread 'main' panicked at 'called Result::unwrap()
on an Err
value: Interrupted system call', src/libcore/result.rs:1009:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:71
at src/libstd/sys_common/backtrace.rs:59
at src/libstd/panicking.rs:211
2: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:227
at src/libstd/panicking.rs:491
3: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:398
4: rust_begin_unwind
at src/libstd/panicking.rs:325
5: core::panicking::panic_fmt
at src/libcore/panicking.rs:95
6: core::result::unwrap_failed
7: es1800_zmqsubr::main
8: std::rt::lang_start::{{closure}}
9: main
10: __libc_start_main
11: _start
Aborted (core dumped)
It works fine with just cargo run, but I need release code.
Any thoughts?
I apologize for the above message. I don't understand why it worked for cargo build, but not for cargo build --release, however I 'fixed' the problem by changing:
let stuff = socket.recv_multipart(0).unwrap();
to:
let mut stuff: Vec<Vec
where I properly catch the ctrl-c error zmq encounters and do not panic, but just print a message and allow the ctrl-c handler catch the ctrl-c as I wanted.
@rotty I can confirm this still happens to me in 0.9, Spec:
MacBook Pro (16-inch, 2019)
MacOS Big Sur 11.4 (20F71)
Rust 1.52.1
zmq 0.9
Code:
extern "C" {
fn signal(_: i32, _: usize) -> usize;
}
extern "C" fn s_signal_handler(_: i32) {}
fn main() {
let ctx = zmq::Context::new();
unsafe {
signal(2, s_signal_handler as usize);
}
let pull_socket = ctx.socket(zmq::PULL).unwrap();
let _ = pull_socket.recv_msg(0).unwrap();
}
I'm then signaling ctrl+C and this is the output:
^Cthread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Interrupted system call', src/main.rs:15:37
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
When my code (which uses
rust-zmq
and currently runs on OS X) is interrupted, the whole program panics. I can verify that according to libc the error code4
equalsEINTR
, see here for details.And yet the error code 4 is not recognized by
zmq::Error::from_raw
, leading to a panic.I would like to discuss 2 changes:
zmq::Error::from_raw
. It basically takes the choice of what to do out of the hands of the library consumer. Instead, I suggest returning some custom error variant (e.g.Unknown
) that contains all relevant information that is currently passed to the panic macro call. This would let a consumer (e.g. my code) work around such issues between encountering them and a fix being available for it.rust-zmq
currently does not detect errors correctly on OS X. Otherwise, the error code 4 would have been mapped properly tozmq::Error::EINTR
.The backtrace:
UPDATE: To deepen the mystery, I have just cloned the repo, checked out the
release/v0.8
branch, and changed thefrom_raw
definition to:What changed here is that I added the
4 => Error::EINTR,
line. The result: A compiler warning:But what is also noteworthy is that my program no longer crashes. So somehow rustc sees 4 as equivalent to
errno::EINTR
. Yet at runtime on OS X that does not seem to hold, otherwise the system would just pickerrno::EINTR
rather than the default case.