Closed jerbob92 closed 1 year ago
thanks for the detailed reproducer!
EDIT: confirmed on native arm64 (Apple M1) with any wasm file
EDIT2: wait no. It just SIGSEGVs because ExportedFunction()
returns nil 🤔
EDIT3: finally, managed to reproduce with linux/riscv64
❯ docker run --platform linux/riscv64 -v $(pwd)/repro:/test -v $(pwd)/repro:/wazero -e WAZEROCLI=/wazero --tmpfs /tmp --rm -t wazero:test
But I can confirm it's only a mismanaged nil ptr.
f := mod.ExportedFunction("iDontExist")
if f == nil {
println("nope")
} else {
f.Call(ctx)
}
prints nope
.
EDIT4: @jerbob92 I think you found bug in the Go compiler
❯ cat reproducer.go
package main
type i interface {
f()
}
func main() {
var ii i
ii.f()
}
⬇️
❯ GOARCH=riscv64 GOOS=linux go build -gcflags=all="-N -l" reproducer.go
❯ docker run --platform linux/riscv64 -v $(pwd)/reproducer:/test -v $(pwd)/reproducer:/wazero -e WAZEROCLI=/wazero --tmpfs /tmp --rm -t wazero:test
💣💥
LOL this is nothing to do with wazero, but simply a bug of Go compiler or QEMU...
$ cat Dockerfile
FROM scratch
CMD ["/test"]
$ docker buildx build -t testriscv --platform linux/riscv64 .
$ cat main.go
package main
func main() {
getter().Call()
}
type iface interface {
Call()
}
func getter() iface {
return nil
}
$ GOARCH=riscv64 GOOS=linux CGO_ENABLED=0 go build -o crash main.go
$ docker run --platform linux/riscv64 -v $(pwd)/crash:/test --tmpfs /tmp --rm -t testriscv
SIGILL: illegal instruction
PC=0x0 m=0 sigcode=1
instruction bytes: 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
goroutine 1 [running]:
runtime/internal/atomic.(*Uint32).Load(...)
/usr/local/go/src/runtime/internal/atomic/types.go:194
runtime.main()
/usr/local/go/src/runtime/proc.go:260 +0x218 fp=0xc00002c7c8 sp=0xc00002c770 pc=0x3dcd8
runtime: g 1: unexpected return pc for runtime.main called from 0xc00002c7ae
---snip---
Closing this as it's out of our hands, and I landed the workaround #1623 as far as we are concerned
Describe the bug This is a result of the issue we found when developing #1611, that code would try to call the exported function
stackRestore
, but that function was not defined in our WASM, because we didn't expect the current tests to reach that code. On some platforms this willSIGILL: illegal instruction
some of the times, at least on arm64 and riscv64.To Reproduce First make sure you can run arm64 in Docker by install qemu:
Create a Dockerfile with the following:
Build the docker image:
Create the following main.go:
Build the binary and run it in Docker:
You might have to run it a few times to trigger it. If you first check the exported function for nil it doesn't have this behaviour.
Expected behavior
ExportedFunction
should always return nil when the function doesn't exist.Environment (please complete the relevant information):
Additional context