Skip to content

poll_oneoff with wasi::EVENTTYPE_FD_READ resulting in EBADF  #440

@dunnock

Description

@dunnock

In the following code compiled using rust 1.40 nightly when passing fd from preopened file I get error code 8 as output event from poll_oneoff. I guess it should not be bad fd since reading from file succeeds?

#![feature(wasi_ext)]
use ::wasi::wasi_unstable as wasi;
use std::os::wasi::io::AsRawFd;
use std::io::prelude::*;

fn main() {
    let mut input = std::fs::File::open("input.txt").expect("file input.txt");
    let mut buf: String = String::new();
    println!("{:?}", input.read_to_string(&mut buf));

    println!("File descriptor: {}", input.as_raw_fd());

    let fd_readwrite = wasi::raw::__wasi_subscription_u_fd_readwrite_t {
        fd: input.as_raw_fd()
    };
    let in_ = [wasi::Subscription {
        userdata: 1,
        type_: wasi::EVENTTYPE_FD_READ,
        u: wasi::raw::__wasi_subscription_u { fd_readwrite },
    }];
    let (res, event) = unsafe {
        let mut out: [wasi::Event; 1] = std::mem::zeroed();
        let res = wasi::poll_oneoff(&in_, &mut out);
        (res, out[0])
    };

    println!("Res = {:?}", res);
    assert_eq!(event.userdata, 1, "event.userdata");
    assert_eq!(event.error, 0, "event.error");
    assert_eq!(event.type_, wasi::EVENTTYPE_FD_READ, "event.type_");
}

Following repo has required setup and test.sh script compiling and running through wasmtime https://github.com/dunnock/poll_oneoff_tests:

poll_oneoff_tests % ./test.sh
    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Ok(2)
File descriptor: 4
Res = Ok(1)
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `8`,
 right: `0`: event.error', src/main.rs:97:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: failed to process main module `target/wasm32-wasi/debug/poll_oneoff_tests.wasm`
    caused by: Instantiation error: Trap occurred while invoking start function: wasm trap: unreachable, source location: @19834

with RUST_LOG=trace:

...
TRACE wasmtime_wasi::syscalls              > path_open(dirfd=3, dirflags=1, path=0x110128, path_len=9, oflags=0x0, fs_rights_base=0xf87febe, fs_rights_inheriting=0xf87febe, fs_flags=0x0, fd=0xffa88)
 TRACE wasi_common::hostcalls_impl::fs      > path_open(dirfd=3, dirflags=1, path_ptr=0x110128, path_len=9, oflags=0x0, fs_rights_base=0xf87febe, fs_rights_inheriting=0xf87febe, fs_flags=0x0, fd_out_ptr=0xffa88)
 TRACE wasi_common::hostcalls_impl::fs      >      | (path_ptr,path_len)='input.txt'
 DEBUG wasi_common::hostcalls_impl::fs_helpers > path_get cur_path = "input.txt"
 DEBUG wasi_common::hostcalls_impl::fs_helpers > path_get path_stack = []
 DEBUG wasi_common::sys::unix::hostcalls_impl::fs_helpers > path_get readlinkat path = "input.txt"
 DEBUG wasi_common::sys::unix::hostcalls_impl::fs         > path_open resolved = PathGet { dirfd: File { fd: 7, path: "/Users/max/src/wasm/poll_oneoff_tests/input", read: true, write: false }, path: "input.txt" }
 DEBUG wasi_common::sys::unix::hostcalls_impl::fs         > path_open oflags = O_NOFOLLOW
 DEBUG wasi_common::sys::unix::hostcalls_impl::fs         > path_open new_fd = 8
 DEBUG wasi_common::sys::unix::fdentry_impl               > Fd 8 is a file
 DEBUG wasi_common::sys::unix::fdentry_impl               > Fd 8 is a file
 TRACE wasi_common::hostcalls_impl::fs                    >      | *fd=4
 TRACE wasi_common::hostcalls                             >     -> errno=__WASI_ESUCCESS
 TRACE wasmtime_wasi::syscalls                            > fd_read(fd=4, iovs=0xff9e0, iovs_len=1, nread=0xff9ec)
 TRACE wasi_common::hostcalls_impl::fs                    > fd_read(fd=4, iovs_ptr=0xff9e0, iovs_len=1, nread=0xff9ec)
 TRACE wasi_common::hostcalls_impl::fs                    >      | *nread=2
 TRACE wasi_common::hostcalls                             >     -> errno=__WASI_ESUCCESS
 TRACE wasmtime_wasi::syscalls                            > fd_read(fd=4, iovs=0xff9e0, iovs_len=1, nread=0xff9ec)
 TRACE wasi_common::hostcalls_impl::fs                    > fd_read(fd=4, iovs_ptr=0xff9e0, iovs_len=1, nread=0xff9ec)
 TRACE wasi_common::hostcalls_impl::fs                    >      | *nread=0
 TRACE wasi_common::hostcalls                             >     -> errno=__WASI_ESUCCESS
 TRACE wasmtime_wasi::syscalls                            > fd_write(fd=1, iovs=0xff9e0, iovs_len=1, nwritten=0xff9e8)
 TRACE wasi_common::hostcalls_impl::fs                    > fd_write(fd=1, iovs_ptr=0xff9e0, iovs_len=1, nwritten=0xff9e8)
Ok(2)
 TRACE wasi_common::hostcalls_impl::fs                    >      | *nwritten=6
 TRACE wasi_common::hostcalls                             >     -> errno=__WASI_ESUCCESS
 TRACE wasmtime_wasi::syscalls                            > fd_write(fd=1, iovs=0xff9e0, iovs_len=1, nwritten=0xff9e8)
 TRACE wasi_common::hostcalls_impl::fs                    > fd_write(fd=1, iovs_ptr=0xff9e0, iovs_len=1, nwritten=0xff9e8)
File descriptor: 4
 TRACE wasi_common::hostcalls_impl::fs                    >      | *nwritten=19
 TRACE wasi_common::hostcalls                             >     -> errno=__WASI_ESUCCESS
 TRACE wasmtime_wasi::syscalls                            > poll_oneoff(in=0xffc08, out=0xffcf8, nsubscriptions=1, nevents=0xffaf0)
 TRACE wasi_common::hostcalls_impl::misc                  > poll_oneoff(input=0xffc08, output=0xffcf8, nsubscriptions=1, nevents=0xffaf0)
 TRACE wasi_common::hostcalls_impl::misc                  >      | *nevents=1
 TRACE wasi_common::hostcalls                             >     -> errno=__WASI_ESUCCESS
 TRACE wasmtime_wasi::syscalls                            > fd_write(fd=1, iovs=0xff9e0, iovs_len=1, nwritten=0xff9e8)
 TRACE wasi_common::hostcalls_impl::fs                    > fd_write(fd=1, iovs_ptr=0xff9e0, iovs_len=1, nwritten=0xff9e8)
Res = Ok(1)
...

Metadata

Metadata

Assignees

Labels

wasi:apiIssues pertaining to the WASI API, not necessarily specific to Wasmtime.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions