Skip to content

os: GOOS=wasip1 GOARCH=wasm the ReadFile function gives -1 as the rootFd to path_open causing Bad file number error #63466

Open
@HarikrishnanBalagopal

Description

@HarikrishnanBalagopal

What version of Go are you using (go version)?

$ go version
go version go1.21.0 darwin/arm64

Does this issue reproduce with the latest release?

Yes, the same issue happens with the master branch binary produced by all.bash
Commit 2744155

$ ../bin/go version
go version devel go1.22-2744155d36 Sun Oct 8 23:15:25 2023 +0000 darwin/arm64
time="2023-10-09T16:14:50Z" level=info msg="start 7!!"
time="2023-10-09T16:14:50Z" level=info msg="pwd: '.'"
time="2023-10-09T16:14:50Z" level=info msg="f: - dep.json"
time="2023-10-09T16:14:50Z" level=info msg="f: - example.c"
time="2023-10-09T16:14:50Z" level=info msg="f: - hello.rs"
panic: open dep.json: Bad file number

goroutine 1 [running]:
main.must(...)
        /Users/haribala/Documents/code/remote/github.com/HarikrishnanBalagopal/test-wasi-fs-browser/main.go:11
main.main()
        /Users/haribala/Documents/code/remote/github.com/HarikrishnanBalagopal/test-wasi-fs-browser/main.go:29 +0x45

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/haribala/Library/Caches/go-build'
GOENV='/Users/haribala/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/haribala/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/haribala/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.21.0/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.21.0/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.0'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/haribala/Documents/code/remote/github.com/HarikrishnanBalagopal/test-wasi-fs-browser/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/81/pzmd85sj2d9dg02xgmd7wlhr0000gn/T/go-build2239353216=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

package main

import (
	"os"

	"github.com/sirupsen/logrus"
)

func must(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	logrus.Infof("start v7!!")
	pwd, err := os.Getwd()
	logrus.Infof("pwd: '%s'", pwd)
	must(err)
	// fs, err := os.ReadDir(".")
	// fs, err := os.ReadDir("/")
	fs, err := os.ReadDir(pwd)
	must(err)
	for _, f := range fs {
		logrus.Infof("f: %+v", f)
	}
	b, err := os.ReadFile("dep.json")
	// b, err := os.ReadFile("/dep.json")
	must(err)
	logrus.Infof("The contents are:\n%s", string(b))
	logrus.Infof("done")
}

The whole project is here https://github.com/HarikrishnanBalagopal/test-wasi-fs-browser
The JS code is here https://github.com/HarikrishnanBalagopal/test-wasi-fs-browser/blob/d105e396d3d2c00bbe37d823279978b030a72a00/public/src/index.js

What did you expect to see?

Compiling with TinyGo CGO_ENABLED=0 tinygo build -o bin/test.wasm -target=wasi . and running in the browser using this WASI virtual filesystem library https://github.com/bjorn3/browser_wasi_shim I get this output

time="2023-10-09T13:58:41Z" level=info msg="start v7!!"
time="2023-10-09T13:58:41Z" level=info msg="pwd: '/'"
time="2023-10-09T13:58:41Z" level=info msg="f: &{parent:/ name:dep.json typ:0 info:<nil>}"
time="2023-10-09T13:58:41Z" level=info msg="f: &{parent:/ name:example.c typ:0 info:<nil>}"
time="2023-10-09T13:58:41Z" level=info msg="f: &{parent:/ name:hello.rs typ:0 info:<nil>}"
time="2023-10-09T13:58:41Z" level=info msg="The contents are:\n{\"a\": 42, \"b\": 12}"
time="2023-10-09T13:58:41Z" level=info msg=done

expected a similar output with the official Go compiler.

What did you see instead?

Compiling with the official Go compiler CGO_ENABLED=0 GOOS=wasip1 GOARCH=wasm go build -o bin/test.wasm . and keeping everything else exactly the same I get this error

time="2023-10-09T14:01:50Z" level=info msg="start v7!!"
time="2023-10-09T14:01:50Z" level=info msg="pwd: '.'"
time="2023-10-09T14:01:50Z" level=info msg="f: - dep.json"
time="2023-10-09T14:01:50Z" level=info msg="f: - example.c"
time="2023-10-09T14:01:50Z" level=info msg="f: - hello.rs"
panic: open dep.json: Bad file number

goroutine 1 [running]:
main.must(...)
        /Users/haribala/Documents/code/remote/github.com/HarikrishnanBalagopal/test-wasi-fs-browser/main.go:11
main.main()
        /Users/haribala/Documents/code/remote/github.com/HarikrishnanBalagopal/test-wasi-fs-browser/main.go:29 +0x44

Context

Doing some debugging by proxying the WASI imports in the browser, I see that -1 is being passed as the file description to the path_open host function https://wasix.org/docs/api-reference/wasi/path_open

# dirfd dirflags path path_len o_flags fs_rights_base fs_rights_inheriting fs_flags fd
proxy for path_open, args: -1 1 21021328 8 0 267910846n 268435455n 0 21281856

For comparison TinyGo provides 3 as the file descriptor (0 stdin, 1 stdout, 2 stderr)

# dirfd dirflags path path_len o_flags fs_rights_base fs_rights_inheriting fs_flags fd
proxy for path_open, args: 3 1 151536 8 0 0n 0n 0 133972

go/src/syscall/fs_wasip1.go

Lines 555 to 556 in 2744155

errno := path_open(
dirFd,

go/src/syscall/fs_wasip1.go

Lines 492 to 493 in 2744155

func preparePath(path string) (int32, unsafe.Pointer, size) {
var dirFd = int32(-1)

Related #60732 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.arch-wasmWebAssembly issues

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions