Skip to content

cmd/compile: program compiles to wasm but is invalid: go:wasmexport: integer too large #73246

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

Closed
davidmdm opened this issue Apr 8, 2025 · 15 comments
Assignees
Labels
arch-wasm WebAssembly issues BugReport Issues describing a possible bug in the Go implementation. compiler/runtime Issues related to the Go compiler and/or runtime. Critical A critical problem that affects the availability or correctness of production systems built using Go FixPending Issues that have a fix which has not yet been reviewed or submitted. NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@davidmdm
Copy link

davidmdm commented Apr 8, 2025

Go version

go1.24.2 darwin/arm64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE='on'
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/Users/davidmdm/go/bin'
GOCACHE='/Users/davidmdm/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/davidmdm/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/s1/hqn8jdf97bj_xvlp070s_mh00000gn/T/go-build3338415171=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/davidmdm/Documents/coding/yokecd/examples/go.mod'
GOMODCACHE='/Users/davidmdm/go/pkg/mod'
GONOPROXY='github.com/davidmdm/*'
GONOSUMDB='github.com/davidmdm/*'
GOOS='darwin'
GOPATH='/Users/davidmdm/go'
GOPRIVATE='github.com/nestoca/*,github.com/davidmdm/*'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/davidmdm/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.2.darwin-arm64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/Users/davidmdm/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='go1.24.2+auto'
GOTOOLDIR='/Users/davidmdm/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.2.darwin-arm64/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.24.2'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I compiled a program to wasm using GOOS=wasip1 GOARCH=wasm and when I tried to execute it with wazero and wasmtime found that the program was invalid.

I have managed to create a minimal reproduction.

Create a new directory and run the following script.

(It seems to only fail if I import the external-secret project and use a wasm export in combination)

set -x

go mod init temp

go get github.com/external-secrets/external-secrets@v0.15.1
go mod tidy

cat <<EOF >main.go
package main

import _ "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"

func main() {}

//go:wasmexport malloc
func malloc(size uint32) uint32 {
	return 0
}
EOF

GOOS=wasip1 GOARCH=wasm go build -o ./temp.wasm .

wazero compile ./temp.wasm || wasmtime compile ./temp.wasm
EOF

GOOS=wasip1 GOARCH=wasm go build -o ./temp.wasm .

wazero compile ./temp.wasm || wasmtime compile ./temp.wasm

What did you see happen?

Both wazero and wasmtime fail to compile the wasm binary produced by the above program.

Wazero:

error compiling wasm binary: invalid function[51716] export["malloc"]: read i32 immediate: overflows a 32-bit integer

Wasmtime:

Error: WebAssembly translation error

Caused by:
    Invalid input WebAssembly code at offset 45267909: invalid var_i32: integer too large

What did you expect to see?

Binary produced by Go Toolchain compiles successfully and can be executed successfully.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Apr 8, 2025
@ldemailly
Copy link

ldemailly commented Apr 8, 2025

can you reduce it to whichever github.com/external-secrets/external-secrets does in init/globals ?
(I assume the problem doesn't occur without

import _ "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"

)

@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Apr 8, 2025
@dmitshur dmitshur added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. arch-wasm WebAssembly issues labels Apr 8, 2025
@dmitshur
Copy link
Contributor

dmitshur commented Apr 8, 2025

CC @golang/wasm.

@Zxilly
Copy link
Member

Zxilly commented Apr 8, 2025

Can you share the WAT format code of function[51716]?

@davidmdm
Copy link
Author

davidmdm commented Apr 8, 2025

@Zxilly as a bit of a high level end user, I am not all too familiar with the tooling for doing that. I can try later today. But the script above should produce the offending binary for you.

@davidmdm
Copy link
Author

davidmdm commented Apr 8, 2025

@Zxilly I have tried running wasm2wat on the binary but get a similar error:

wasm2wat ./temp.wasm -o ./temp.wat
2b2bbc1: error: unable to read i32 leb128: i32.const value

Running in verbose mode does not seem to give us more information:

    ...
    OnGlobalGetExpr(index: 0)
    OnI32ConstExpr(16 (0x10))
    OnBinaryExpr("i32.sub" (107))
    OnGlobalSetExpr(index: 0)
    OnGlobalGetExpr(index: 0)
    OnLocalGetExpr(index: 0)
    OnStoreExpr(opcode: "i32.store" (54), memidx: 0, align log2: 2, offset: 0)
    OnGlobalGetExpr(index: 0)
    OnI32ConstExpr(8 (0x8))
    OnBinaryExpr("i32.sub" (107))
    OnGlobalSetExpr(index: 0)
    OnGlobalGetExpr(index: 0)
    OnI64ConstExpr(3657695233 (0xda040001))
    OnStoreExpr(opcode: "i64.store" (55), memidx: 0, align log2: 3, offset: 0)
    OnI32ConstExpr(0 (0x0))
    OnCallExpr(func_index: 51750)
    OnIfExpr(sig: void)
2b2bbc1: error: unable to read i32 leb128: i32.const value

@Zxilly
Copy link
Member

Zxilly commented Apr 8, 2025

I've reproduce the problem and got the binary, thanks.

@Zxilly
Copy link
Member

Zxilly commented Apr 8, 2025

I wrote a patch to try to fix this issue, but I'm not quite sure if I'm doing it right.

cc @cherrymui

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/663995 mentions this issue: cmd/internal/obj/wasm: use i64 for large return addr

@cherrymui
Copy link
Member

Thanks for the report. This looks similar (and probably related) to #64856. When it have more than 32K of functions, a number of places in the code don't handle that many functions well. One difference is that this is signed integer overflow, i.e. more than 32K but not 64K. The CL above may be part of the fix, but it is probably not enough, especially once we get to more than 64K functions, it would certainly be not enough. I'll continue looking into it, along with #64856.

@cherrymui
Copy link
Member

@davidmdm Could you try if the CL above fix the issue? It probably makes it build and pass verification. It would still be good to know if the resulting binary runs okay. Thanks,

The easiest way to do this is to use the gotip command (https://golang.org/dl/gotip) and run gotip download 663995. Then use gotip as the go command, e.g. gotip build .... (Manually downloading the CL and building the toolchain also works.)

@davidmdm
Copy link
Author

davidmdm commented Apr 9, 2025

@cherrymui

I confirm that CL 663995 successfully compiles and that wasm binary runs as expected!

Now, the question that I am afraid to ask, is this the kind of bug I need to wait 6 months for Go1.25? Or is it something sneaky that can be put through a patch?

Thanks for the great turn around!

@cherrymui
Copy link
Member

cherrymui commented Apr 9, 2025

We probably can backport to 1.24. Wasmexport is a new feature in Go 1.24. This fixes a case that was missed in 1.24.

Even if we don't backport, we don't need to wait for 6 months. Go 1.25 RC is expected to be released early June, 2 months from now, and 1.25.0 in August, 4 months from now.

@cherrymui
Copy link
Member

@gopherbot please backport this to Go 1.24 release. Wasmexport is a new feature in Go 1.24. This fixes a miscompilation in a case that was missed in 1.24. Thanks.

@gopherbot
Copy link
Contributor

Backport issue(s) opened: #73281 (for 1.24).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

@dmitshur dmitshur added this to the Go1.25 milestone Apr 9, 2025
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. FixPending Issues that have a fix which has not yet been reviewed or submitted. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 9, 2025
@mknyszek mknyszek moved this to In Progress in Go Compiler / Runtime Apr 9, 2025
@mknyszek mknyszek moved this from In Progress to All-But-Submitted in Go Compiler / Runtime Apr 9, 2025
@github-project-automation github-project-automation bot moved this from All-But-Submitted to Done in Go Compiler / Runtime Apr 10, 2025
@prattmic prattmic added the Critical A critical problem that affects the availability or correctness of production systems built using Go label Apr 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly issues BugReport Issues describing a possible bug in the Go implementation. compiler/runtime Issues related to the Go compiler and/or runtime. Critical A critical problem that affects the availability or correctness of production systems built using Go FixPending Issues that have a fix which has not yet been reviewed or submitted. NeedsFix The path to resolution is known, but the work has not been done.
Projects
Development

Successfully merging a pull request may close this issue.

8 participants