Stream: git-wasmtime

Topic: wasmtime / issue #8037 fd_write ignores iovs_len > 1


view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 16:33):

ThisGuyCodes added the bug label to Issue #8037.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 16:33):

ThisGuyCodes opened issue #8037:

Am I crazy? I thought I might be misunderstanding something, but then I found someone else's example online that also doesn't work.

Test Case

;; hello.wat
(module
    ;; define the expected type for fd_write
    (type $write_type (func (param i32 i32 i32 i32) (result i32)))
    (import "wasi_snapshot_preview1" "fd_write" (func $write (type $write_type)))

    ;; Define a memory that is one page in size (64KiB).
    (memory (export "memory") 1)

    ;; At offset 66 and 80 in the memory, we store the data.
    (data (i32.const 66) "Hello, World!\n")
    (data (i32.const 80) "Howdy!\n")


    (func $main (export "_start")
        ;; Store the iovs
        (i32.store (i32.const 0) (i32.const 66)) ;; Start of data (= *buf)
        (i32.store (i32.const 4) (i32.const 14)) ;; Length of data (= buf_len)

        (i32.store (i32.const 8) (i32.const 80)) ;; Start of data (= *buf)
        (i32.store (i32.const 12) (i32.const 8)) ;; Length of data (= buf_len)

        i32.const 1 ;; fd param. In Unix this means: 0 = stdin, 1 = stdout, 2 = stderr

        ;; here are different combinations possible:
        ;; 0,1 would read only "Hello, World!"
        ;; 8,1 would read only 'Howdy'
        i32.const 0 ;; iovs -> Offset. Points to first iovec
        i32.const 2 ;; iovs_len -> How many iovs should be read, set it to 2 to read also Howdy

        i32.const 92 ;; Pointer to the place in memory where the number of written bytes shall be placed.

        call $write ;; call fd_write and drop the result code
        drop
    )
)

Steps to Reproduce

wasmtime hello.wat

Expected Results

Hello, World!
Howdy!

Actual Results

Hello, World!

Versions and Environment

Wasmtime version or commit: wasmtime-cli 18.0.2 (90db6e99f 2024-02-28)

Operating system: MacOS 14.3.1

Architecture: arm64 (M1 Pro)

Extra Info

Anything else you'd like to add?

view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 16:33):

ThisGuyCodes edited issue #8037:

Am I crazy? I thought I might be misunderstanding something, but then I found someone else's example online that also doesn't work.

Test Case

;; hello.wat
(module
    ;; define the expected type for fd_write
    (type $write_type (func (param i32 i32 i32 i32) (result i32)))
    (import "wasi_snapshot_preview1" "fd_write" (func $write (type $write_type)))

    ;; Define a memory that is one page in size (64KiB).
    (memory (export "memory") 1)

    ;; At offset 66 and 80 in the memory, we store the data.
    (data (i32.const 66) "Hello, World!\n")
    (data (i32.const 80) "Howdy!\n")


    (func $main (export "_start")
        ;; Store the iovs
        (i32.store (i32.const 0) (i32.const 66)) ;; Start of data (= *buf)
        (i32.store (i32.const 4) (i32.const 14)) ;; Length of data (= buf_len)

        (i32.store (i32.const 8) (i32.const 80)) ;; Start of data (= *buf)
        (i32.store (i32.const 12) (i32.const 8)) ;; Length of data (= buf_len)

        i32.const 1 ;; fd param. In Unix this means: 0 = stdin, 1 = stdout, 2 = stderr

        ;; here are different combinations possible:
        ;; 0,1 would read only "Hello, World!"
        ;; 8,1 would read only 'Howdy'
        i32.const 0 ;; iovs -> Offset. Points to first iovec
        i32.const 2 ;; iovs_len -> How many iovs should be read, set it to 2 to read also Howdy

        i32.const 92 ;; Pointer to the place in memory where the number of written bytes shall be placed.

        call $write ;; call fd_write and drop the result code
        drop
    )
)

Steps to Reproduce

wasmtime hello.wat

Expected Results

Hello, World!
Howdy!

Actual Results

Hello, World!

Versions and Environment

Wasmtime version or commit: wasmtime-cli 18.0.2 (90db6e99f 2024-02-28)

Operating system: MacOS 14.3.1

Architecture: arm64 (M1 Pro)

view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 16:38):

bjorn3 commented on issue #8037:

The wasi-preview1 support in wasmtime is since recently layered on top of wasi 0.2, which doesn't have support for vectored reads and writes. To avoid breaking the atomicity guarantee of readv and writev (all parts that have been read/written have been done so atomically), the current implementation of fd_read and fd_write only look at the first iovec and ignore the rest. This is an entirely valid implementation. reads and writes in both unix and wasi are allowed to only partially happen. The OS/wasi runtime just has to return the exact amount of bytes that was read/written. The program can then try writing the rest.

By the way this is a duplicate of https://github.com/bytecodealliance/wasmtime/issues/7757.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 16:51):

ThisGuyCodes commented on issue #8037:

@bjorn3 is it required that fd_write not perform any internal allocations? While it seems the current implementation is _technically_ correct I wonder if the atomicity guarantee could be maintained while still supporting vectored writes.

I have difficulty believing that any implementation calling this with a vector would prefer to loop. And if they did they could optimize to do a no-alloc version with one write at a time themselves.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 16:54):

bjorn3 commented on issue #8037:

If you are using a vectored write that is likely because you want to avoid having to copy the data to a new allocation before calling the write, right?

view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 18:02):

ThisGuyCodes commented on issue #8037:

I suppose that makes sense. And if wasi 0.2 doesn't allow it anyway less and less implementations are going to target using vectored writes anyway.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 01 2024 at 18:02):

ThisGuyCodes edited a comment on issue #8037:

I suppose that makes sense. And if wasi 0.2 doesn't allow it anyway less and less implementations are going to target using vectored writes over time.


Last updated: Dec 23 2024 at 12:05 UTC