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

Segmentation fault compiling to WASM #4638

Open
upsj opened this issue Nov 30, 2024 · 3 comments
Open

Segmentation fault compiling to WASM #4638

upsj opened this issue Nov 30, 2024 · 3 comments
Labels
wasm WebAssembly

Comments

@upsj
Copy link

upsj commented Nov 30, 2024

I am trying to build a WASM plugin for the D2 diagram framework to be used as a plugin in Typst. The compilation is failing with a segmentation violation in the compiler:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x38 pc=0x103250730]

goroutine 918 [running]:
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402b3484b0, {0x1402928cf10, 0x6, 0x14033c61b60?}, 0x1400bfff050, {0x1402463a570, 0x28})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:361 +0x34e0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97fef0, {0x1400abfdf10, 0x2, 0x14033c60210?}, 0x1400bfbd410, {0x1402463a4b0, 0x24})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97fea0, {0x1400ab5c290, 0x3, 0x14033c5b740?}, 0x1400bfaa630, {0x140144c0120, 0x20})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97fe00, {0x1400a009a10, 0x2, 0x14033c556f8?}, 0x1400bf7ec90, {0x140143ff660, 0x1c})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97fdb0, {0x1400820a990, 0x2, 0x14033c53a58?}, 0x1400b9da3c0, {0x1402b751278, 0x18})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97fd60, {0x1402c905790, 0x2, 0x14033b4f728?}, 0x1400b6f8360, {0x1400d52df08, 0x14})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97fa90, {0x1402c6bd790, 0x5, 0x108e21220?}, 0x1400ada4c00, {0x14032339310, 0x10})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97fa40, {0x1402bef0710, 0x5, 0x108e21220?}, 0x14010b2da40, {0x1402701c7a0, 0xc})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402c97f720, {0x1402b41bf10, 0x5, 0x108e21220?}, 0x1402b37c690, {0x14032ae3240, 0x8})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.(*runner).run(0x14029f52000, 0x1402b408f50, {0x0, 0x0, 0x1?}, 0x0, {0x107690906, 0x4})
        /Users/runner/work/tinygo/tinygo/interp/interpreter.go:552 +0x67d0
github.com/tinygo-org/tinygo/interp.Run({0x139b120e0?}, 0x29e8d60800?, 0x0?)
        /Users/runner/work/tinygo/tinygo/interp/interp.go:121 +0x4dc
github.com/tinygo-org/tinygo/builder.optimizeProgram({0x361adc400?}, 0x14000132100, 0x1400026c630)
        /Users/runner/work/tinygo/tinygo/builder/build.go:1114 +0x3c
github.com/tinygo-org/tinygo/builder.Build.func5(0x1402c9348a0?)
        /Users/runner/work/tinygo/tinygo/builder/build.go:583 +0x4b0
github.com/tinygo-org/tinygo/builder.runJob(0x1402c934900, 0x1402c98c000)
        /Users/runner/work/tinygo/tinygo/builder/jobs.go:212 +0x48
created by github.com/tinygo-org/tinygo/builder.runJobs in goroutine 1
        /Users/runner/work/tinygo/tinygo/builder/jobs.go:113 +0x43c

To reproduce this, place the following file in the root of a cloned D2 repository https://github.com/terrastruct/d2 and try to compile it with

GOOS=wasip1 GOARCH=wasm tinygo build -buildmode=c-shared -o example.wasm example.go
package main

import (
	"context"
	"unsafe"

	"oss.terrastruct.com/d2/d2graph"
	"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
	"oss.terrastruct.com/d2/d2lib"
	"oss.terrastruct.com/d2/d2renderers/d2svg"
	"oss.terrastruct.com/d2/d2themes/d2themescatalog"
	"oss.terrastruct.com/d2/lib/textmeasure"
	"oss.terrastruct.com/util-go/go2"
)

//go:wasmimport typst_env wasm_minimal_protocol_write_args_to_buffer
func wasm_minimal_protocol_write_args_to_buffer(ptr unsafe.Pointer)

//go:wasmimport typst_env wasm_minimal_protocol_send_result_to_host
func wasm_minimal_protocol_send_result_to_host(ptr unsafe.Pointer, size int32)

//go:wasmexport example
func example(input_size int32) int32 {
	input := make([]byte, input_size)
	wasm_minimal_protocol_write_args_to_buffer(unsafe.Pointer(&input[0]))
	ruler, _ := textmeasure.NewRuler()
	layoutResolver := func(engine string) (d2graph.LayoutGraph, error) {
		return d2dagrelayout.DefaultLayout, nil
	}
	renderOpts := &d2svg.RenderOpts{
		Pad:     go2.Pointer(int64(5)),
		ThemeID: &d2themescatalog.GrapeSoda.ID,
	}
	compileOpts := &d2lib.CompileOptions{
		LayoutResolver: layoutResolver,
		Ruler:          ruler,
	}
	diagram, _, _ := d2lib.Compile(context.Background(), "x -> y", compileOpts, renderOpts)
	output, _ := d2svg.Render(diagram, renderOpts)
	wasm_minimal_protocol_send_result_to_host(unsafe.Pointer(&output[0]), int32(len(output)))
	return 0
}

func main() {}

Hardware:
M2 Mac

Version:

 tinygo version 0.34.0 darwin/arm64 (using go version go1.23.3 and LLVM version 18.1.2)
@upsj
Copy link
Author

upsj commented Nov 30, 2024

The issue also occurs on a x86_64 system with version

tinygo version 0.34.0 linux/amd64 (using go version go1.23.1 and LLVM version 18.1.2)

Unfortunately I know too little about go debugging to be able to track down which function causes these issues, but it seems to be related to compile-time evaluation of initialization functions.

@deadprogram deadprogram added the wasm WebAssembly label Dec 4, 2024
@dgryski
Copy link
Member

dgryski commented Dec 4, 2024

We should probably add a -internal-interp-debug flag that spits out which package is trying to be compiled during the interp phase. I had a patch somewhere that did that, but I can clean it up again and make it actually useful rather than just a hack.

@aykevl
Copy link
Member

aykevl commented Dec 5, 2024

@dgryski yes sounds like a good idea!

@upsj I have reproduced this issue, but haven't looked into it further yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wasm WebAssembly
Projects
None yet
Development

No branches or pull requests

4 participants