summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-08-01 19:39:05 +0000
committerbors <bors@rust-lang.org>2018-08-01 19:39:05 +0000
commit8318a3ec1c1f13aab21d0a74ac9a7cf618bb2261 (patch)
tree1bb71f17231537351cd6aa37622ca9149a1489ee
parent7b45a7cb55ae647cbd9cbf58df9a85efdc7f7f1e (diff)
parentd213c3acbd1e70f40702bf5f2d31dc0c1f323dd7 (diff)
downloadrust-libc-8318a3ec1c1f13aab21d0a74ac9a7cf618bb2261.tar.gz
Auto merge of #1053 - papertigers:illumos-epoll-event, r=alexcrichton
illumos epoll_event struct should be packed While attempting to run `cargo test` within the mio crate on illumos I noticed a number of the tests fail. Digging into the various epoll calls I discovered that the epoll_event struct was misaligned due to extra padding. The fix is to pack the epoll_event struct with the same compiler setting that the linux variant is using. A simple rust example that demonstrates the issue: ```rust extern crate libc; use libc::epoll_event; use std::mem; fn main() { println!("{}", mem::size_of::<u64>()); println!("{}", mem::size_of::<epoll_event>()); } ``` Running the above code on Linux results in: ``` 8 12 ``` while on illumos it currently results in: ``` 8 16 ``` Looking at the `test_close_on_drop` test from mio I traced the `epoll_ctl` calls and saw the following: ``` [root@rustdev ~/src/mio]# dtrace -wn 'pid$target::epoll_ctl:entry {this->ev = arg3; printf("%d\n", arg2); print((struct epoll_event *)this->ev); stop()}' -c "/root/src/mio/target/debug/deps/test-109e1422fb40f621 test_close_on_drop" dtrace: description 'pid$target::epoll_ctl:entry ' matched 1 probe dtrace: allowing destructive actions running 1 test CPU ID FUNCTION:NAME 6 92874 epoll_ctl:entry 4 struct epoll_event * 0xfffffc7fee7feda8 test test_close_on_drop::test_close_on_drop ... test test_close_on_drop::test_close_on_drop has been running for over 60 seconds 6 92874 epoll_ctl:entry 6 struct epoll_event * 0xfffffc7fee7fee18 ^[[A 6 92874 epoll_ctl:entry 7 struct epoll_event * 0xfffffc7fee7fee18 ``` I dumped each of the epoll_event's with mdb: ``` [root@rustdev ~/src/mio]# mdb -Fp 219856 Loading modules: [ libumem.so.1 libc.so.1 ] > 0xfffffc7fee7feda8::print mdb: no symbol information for 0xfffffc7fee7feda8: no symbol corresponds to address > 0xfffffc7fee7feda8::print struct epoll_event { events = 0x80000001 data = { ptr = 0xfffffffffffffc7f fd = 0xfffffc7f u32 = 0xfffffc7f u64 = 0xfffffffffffffc7f } } > [root@rustdev ~/src/mio]# prun 219856 [root@rustdev ~/src/mio]# mdb -Fp 219856 Loading modules: [ libumem.so.1 libc.so.1 ] > 0xfffffc7fee7fee18::print struct epoll_event { events = 0x80000001 data = { ptr = 0 fd = 0 u32 = 0 u64 = 0 } } > [root@rustdev ~/src/mio]# prun 219856 [root@rustdev ~/src/mio]# mdb -Fp 2198 Loading modules: [ libumem.so.1 libc.so.1 ] > 0xfffffc7fee7fee18::print struct epoll_event { events = 0x80000004 data = { ptr = 0x100000000 fd = 0 u32 = 0 u64 = 0x100000000 } } ``` The output from the last two `epoll_event`'s represent `Token(0)` the Client and `Token(1)` from the mio test. The first one however is from `AWAKEN` which is defined as `usize::MAX`. This value should be 18446744073709551615. However if we convert the hex value we see something else: ``` > 0xfffffffffffffc7f=E 18446744073709550719 ``` Because of the extra 4 bytes of padding currently present in the illumos `epoll_event` definition the low order bits are picking up some junk from other memory. All of the poll-related mio tests pass with this change. Two other tests are still failing, which appears to be caused by an OS bug, not a problem with mio or libc.
-rw-r--r--src/unix/solaris/mod.rs1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/unix/solaris/mod.rs b/src/unix/solaris/mod.rs
index db122dea26..f285191677 100644
--- a/src/unix/solaris/mod.rs
+++ b/src/unix/solaris/mod.rs
@@ -354,6 +354,7 @@ s! {
pub portev_user: *mut ::c_void,
}
+ #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), repr(packed))]
pub struct epoll_event {
pub events: ::uint32_t,
pub u64: ::uint64_t,