diff options
author | bors <bors@rust-lang.org> | 2018-08-01 19:39:05 +0000 |
---|---|---|
committer | bors <bors@rust-lang.org> | 2018-08-01 19:39:05 +0000 |
commit | 8318a3ec1c1f13aab21d0a74ac9a7cf618bb2261 (patch) | |
tree | 1bb71f17231537351cd6aa37622ca9149a1489ee | |
parent | 7b45a7cb55ae647cbd9cbf58df9a85efdc7f7f1e (diff) | |
parent | d213c3acbd1e70f40702bf5f2d31dc0c1f323dd7 (diff) | |
download | rust-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.rs | 1 |
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, |