Open uhyo opened 1 year ago
Trying to follow the recreate following the instructions on what is in the main branch for Node.js I get:
root@cff172256677:~/rust-wasi-readdir# ../node/node --experimental-wasi-unstable-preview1 run-node-wasi.mjs
(node:88306) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Calling fs::read_dir
fd_readdir(4,1065088,128,0,1047548) = 0
offset = 0 { d_next: 14n, d_ino: 0n, d_namlen: 4, d_type: 3, name: '.git' }
offset = 28 { d_next: 17n, d_ino: 0n, d_namlen: 10, d_type: 4, name: '.gitignore' }
offset = 62 { d_next: 20n, d_ino: 0n, d_namlen: 10, d_type: 4, name: 'Cargo.lock' }
file:///root/rust-wasi-readdir/run-node-wasi.mjs:30
const name = decoder.decode(new Uint8Array(resultBuf, offset + 24, dirent.d_namlen));
^
RangeError: Invalid typed array length: 10
at new Uint8Array (<anonymous>)
at wasi.wasiImport.fd_readdir (file:///root/rust-wasi-readdir/run-node-wasi.mjs:30:33)
at wasi::lib_generated::fd_readdir::h99e93ea1726a60a1 (wasm://wasm/008d5366:wasm-function[212]:0x12dd4)
at <std::sys::wasi::fs::ReadDir as core::iter::traits::iterator::Iterator>::next::h78f71fa31b6d237f (wasm://wasm/008d5366:wasm-function[24]:0x6858)
at <std::fs::ReadDir as core::iter::traits::iterator::Iterator>::next::h15f0dfa6aec99ed5 (wasm://wasm/008d5366:wasm-function[106]:0xef8e)
at rust_wasi_readdir::main::hd7fee8bf240a7350 (wasm://wasm/008d5366:wasm-function[10]:0x254d)
at core::ops::function::FnOnce::call_once::h6cf85a7bce0f2d1a (wasm://wasm/008d5366:wasm-function[245]:0x1370f)
at std::sys_common::backtrace::__rust_begin_short_backtrace::h389a6674b2acf4bb (wasm://wasm/008d5366:wasm-function[244]:0x136d9)
at std::rt::lang_start::{{closure}}::haccc3febcb60cb5f (wasm://wasm/008d5366:wasm-function[154]:0x1156e)
at std::rt::lang_start_internal::h38aaea5d7881ae71 (wasm://wasm/008d5366:wasm-function[40]:0x9383)
Node.js v20.0.0-pre
If I comment out the instumentaion that seems to be failing I get:
oot@cff172256677:~/rust-wasi-readdir# ../node/node --experimental-wasi-unstable-preview1 run-node-wasi.mjs
(node:88318) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Calling fs::read_dir
Entry /.git
Entry /.gitignore
Entry /Cargo.lock
Entry /Cargo.toml
Entry /README.md
Entry /run-deno-wasi.ts
Entry /run-wasmtime-wasi.sh
Entry /src
Entry /target
Entry /run-node-wasi.mjs
This is on ubuntu x86.
Same results for me if I use 19.8.1 on ubuntu x86 as well:
root@cff172256677:~/rust-wasi-readdir# /root/node-v19.8.1-linux-x64/bin/node --experimental-wasi-unstable-preview1 run-node-wasi.mjs
(node:88361) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Calling fs::read_dir
Entry /.git
Entry /.gitignore
Entry /Cargo.lock
Entry /Cargo.toml
Entry /README.md
Entry /run-deno-wasi.ts
Entry /run-wasmtime-wasi.sh
Entry /src
Entry /target
Entry /run-node-wasi.mjs
Unfortunately I don't have an ARM OSX machine where docker etc can be installed to test there. @uhyo have you recreated on any other platform/OS combinations?
Sorry, I haven't tested on any other platforms. It's not surprising if it is specific to Mac.
It might be specific to a file system type, so here is additional information:
We discussed in the uvwasi team meeting yesterday and @cjihrig is going to take a look as he as an M1 mac.
Basically the example from https://doc.rust-lang.org/std/fs/struct.DirEntry.html loops forever (going through the same 3 files out of ~20 in the directory) with node v20.11.1
and the wasi preview1 target on macOS. Adding that here for future reference in case more people run into this.
use std::fs;
if let Ok(entries) = fs::read_dir(".") {
for entry in entries {
if let Ok(entry) = entry {
// Here, `entry` is a `DirEntry`.
if let Ok(metadata) = entry.metadata() {
// Now let's show our entry's permissions!
println!("{:?}: {:?}", entry.path(), metadata.permissions());
} else {
println!("Couldn't get metadata for {:?}", entry.path());
}
}
}
}
Version
v19.8.1
Platform
Darwin uhyo 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:19:52 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T6000 arm64
Subsystem
No response
What steps will reproduce the bug?
Create a WASM binary that calls the fd_readdir function with a non-zero
cookie
argument.Reproduction repository: https://github.com/uhyo/rust-wasi-readdir
Example Rust code that demonstrates the problem
```rust use std::{env, fs, io}; fn main() -> io::Result<()> { println!("Calling fs::read_dir"); for entry in fs::read_dir(env::current_dir()?)? { let entry = entry?; println!("Entry {}", entry.path().display()); } Ok(()) } ```How often does it reproduce? Is there a required condition?
always
What is the expected behavior? Why is that the expected behavior?
A typical use case of the
fd_readdir
function is to repeatedly call it until the caller can retrieve all entries in a directory. Thecookie
parameter is used as a cursor so that the function can know where in the given directory to continue from. Thefd_readdir
should respect thecookie
parameter. (Read more in the reproduction repository's README)What do you see instead?
Actually, the
fd_readdir
function ignores thecookie
parameters and always returns the same set of entries. The caller falls into an infinite loop.Log of `fd_readdir` calls and how Node.js responded to them
``` fd_readdir(4,1065824,128,0,1047548) = 0 offset = 0 { d_next: 0n, d_ino: 0n, d_namlen: 17, d_type: 4, name: 'run-node-wasi.mjs' } offset = 41 { d_next: 1n, d_ino: 0n, d_namlen: 10, d_type: 4, name: 'Cargo.toml' } offset = 75 { d_next: 2n, d_ino: 0n, d_namlen: 20, d_type: 4, name: 'run-wasmtime-wasi.sh' } (offset = 119) Entry /run-node-wasi.mjs Entry /Cargo.toml Entry /run-wasmtime-wasi.sh fd_readdir(4,1065824,128,2,1047548) = 0 offset = 0 { d_next: 0n, d_ino: 0n, d_namlen: 17, d_type: 4, name: 'run-node-wasi.mjs' } offset = 41 { d_next: 1n, d_ino: 0n, d_namlen: 10, d_type: 4, name: 'Cargo.toml' } offset = 75 { d_next: 2n, d_ino: 0n, d_namlen: 20, d_type: 4, name: 'run-wasmtime-wasi.sh' } (offset = 119) Entry /run-node-wasi.mjs Entry /Cargo.toml Entry /run-wasmtime-wasi.sh fd_readdir(4,1065824,128,2,1047548) = 0 offset = 0 { d_next: 0n, d_ino: 0n, d_namlen: 17, d_type: 4, name: 'run-node-wasi.mjs' } offset = 41 { d_next: 1n, d_ino: 0n, d_namlen: 10, d_type: 4, name: 'Cargo.toml' } offset = 75 { d_next: 2n, d_ino: 0n, d_namlen: 20, d_type: 4, name: 'run-wasmtime-wasi.sh' } (offset = 119) Entry /run-node-wasi.mjs Entry /Cargo.toml Entry /run-wasmtime-wasi.sh fd_readdir(4,1065824,128,2,1047548) = 0 offset = 0 { d_next: 0n, d_ino: 0n, d_namlen: 17, d_type: 4, name: 'run-node-wasi.mjs' } offset = 41 { d_next: 1n, d_ino: 0n, d_namlen: 10, d_type: 4, name: 'Cargo.toml' } offset = 75 { d_next: 2n, d_ino: 0n, d_namlen: 20, d_type: 4, name: 'run-wasmtime-wasi.sh' } (offset = 119) Entry /run-node-wasi.mjs Entry /Cargo.toml Entry /run-wasmtime-wasi.sh fd_readdir(4,1065824,128,2,1047548) = 0 offset = 0 { d_next: 0n, d_ino: 0n, d_namlen: 17, d_type: 4, name: 'run-node-wasi.mjs' } offset = 41 { d_next: 1n, d_ino: 0n, d_namlen: 10, d_type: 4, name: 'Cargo.toml' } offset = 75 { d_next: 2n, d_ino: 0n, d_namlen: 20, d_type: 4, name: 'run-wasmtime-wasi.sh' } (offset = 119) ```Additional information
No response