Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasm: simple call of wasm exported function raises an error "out of bounds memory access" #71240

Open
snaffi opened this issue Jan 13, 2025 · 3 comments
Labels
BugReport Issues describing a possible bug in the Go implementation. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Milestone

Comments

@snaffi
Copy link

snaffi commented Jan 13, 2025

Go version

go version go1.24rc1 linux/arm64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='on'
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/.jbdevcontainer/go-build'
GODEBUG=''
GOENV='/.jbdevcontainer/config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3652802248=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/IdeaProjects/wasm-1-24/go.mod'
GOMODCACHE='/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/.jbdevcontainer/config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='go1.24rc1'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I'm trying to call simple wasm exported Go function from wasmtime and wazero runtimes.

wasm.go

GOOS=wasip1 GOARCH=wasm go build -o out.wasm -buildmode=c-shared ./wasm/

//go:build wasm

package main

import "fmt"

//go:wasmexport SuperFunction
func SuperFunction(x, y int32) int32 {
	return x + y
} // OK

func main() {

}

wasmtime_main.go

package main

import (
	"context"
	_ "embed"
	"fmt"
	"log"
	"os"
	"unsafe"

	"github.com/bytecodealliance/wasmtime-go"
)

func memoryLimit(megabytes uint32) uint32 {
	const wazeroPageSize = 64
	kilobytes := megabytes * 1024
	return kilobytes / wazeroPageSize
}

//go:embed out.wasm
var wasmModule []byte

func main() {
	// Almost all operations in wasmtime require a contextual `store`
	// argument to share, so create that first
	engine := wasmtime.NewEngine()
	//store.SetWasi()

	// Once we have our binary `wasm` we can compile that into a `*Module`
	// which represents compiled JIT code.
	module, err := wasmtime.NewModule(engine, wasmModule)
	if err != nil {
		log.Fatal(err)
	}

	// Create a linker with WASI functions defined within it
	linker := wasmtime.NewLinker(engine)
	err = linker.DefineWasi()
	if err != nil {
		log.Fatal(err)
	}

	// Configure WASI imports to write stdout into a file, and then create
	// a `Store` using this wasi configuration.
	wasiConfig := wasmtime.NewWasiConfig()
	store := wasmtime.NewStore(engine)
	store.SetWasi(wasiConfig)
	instance, err := linker.Instantiate(store, module)
	if err != nil {
		log.Fatal(err)
	}

	// After we've instantiated we can lookup our `run` function and call
	// it.
	run := instance.GetFunc(store, "SuperFunction")
	_, err = run.Call(store, 96, 55)
	if err != nil {
		log.Fatal(err)
	}
}

wazero_main.go

package main

import (
	"context"
	_ "embed"
	"fmt"
	"log"
	"os"
	"unsafe"

	"github.com/tetratelabs/wazero"
	"github.com/tetratelabs/wazero/api"
	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)

func main() {
	ctx := context.Background()
	runtime := wazero.NewRuntimeWithConfig(
		ctx,
		wazero.
			NewRuntimeConfig().
			WithCoreFeatures(api.CoreFeaturesV2).
			WithMemoryLimitPages(memoryLimit(256)),
	)
	_, err := wasi_snapshot_preview1.Instantiate(ctx, runtime)
	if err != nil {
		panic(err)
	}

	builder := runtime.NewHostModuleBuilder("env")
	wasi_snapshot_preview1.NewFunctionExporter().ExportFunctions(builder)
	_, err = builder.Instantiate(ctx)
	if err != nil {
		panic(err)
	}

	compiledModule, err := runtime.CompileModule(ctx, wasmModule)
	if err != nil {
		panic(fmt.Errorf("can't compile WASM module: %w", err))
	}

	mod, err := runtime.InstantiateModule(
		ctx,
		compiledModule,
		wazero.
			NewModuleConfig().
			WithStdout(os.Stdout).
			WithStderr(os.Stderr),
	)
	if err != nil {
		panic(fmt.Errorf("can't instantiate module: %w", err))
	}

	funcName := "SuperFunction"
	targetFunc := mod.ExportedFunction(funcName)
	if targetFunc == nil {
		panic(fmt.Errorf("target function not found: %s", funcName))
	}

	mod.Memory().Grow(2)
	res, err := targetFunc.Call(ctx, 96, 55)
	//res, err := targetFunc.Call(ctx)
	fmt.Println(res, err)

	fmt.Println(targetFunc.Definition().DebugName())
	fmt.Println(targetFunc.Definition().Name())
	fmt.Println(targetFunc.Definition().ParamTypes())
	fmt.Println(targetFunc.Definition().ParamNames())

}

What did you see happen?

I got out of bounds memory access on wazero and wasmtime runtime

What did you expect to see?

I expect function execution without any error.

@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Jan 13, 2025
@mknyszek
Copy link
Contributor

CC @cherrymui

@mknyszek mknyszek added this to the Go1.24 milestone Jan 13, 2025
@mknyszek mknyszek added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker labels Jan 13, 2025
@mknyszek
Copy link
Contributor

Marking as a release-blocker since this may be a bug in a new feature shipping in Go 1.24.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Projects
None yet
Development

No branches or pull requests

3 participants