tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

#BUG# runtime error: nil pointer dereference (WASI)

Open vnaki opened this issue 1 year ago • 6 comments

wasi output error:

panic: runtime error: nil pointer dereference
panic: unreachable

TinyGo version:

tinygo version 0.28.1 darwin/amd64 (using go version go1.20.1 and LLVM version 15.0.0)

Command line:

tinygo build -o wasi.wasm -target=wasi main.go

Here 2 cases:


//export run
func run() {
  var wg = new(sync.WaitGroup)
  go func() {
     println("goroutine")
     wg.Done()
  }()
  wg.Add(1)  // here error occur
  wg.Wait()
}

or

//export run
func run() {
   time.Sleep(time.Second)
}

Errors will occur above!

vnaki avatar Jun 18 '23 05:06 vnaki

This is basically https://github.com/tinygo-org/tinygo/issues/2735 ; the runtime isn't initialized.

dgryski avatar Jul 04 '23 20:07 dgryski

@dgryski are you sure you meant #2735 ?

deadprogram avatar Jul 27 '23 15:07 deadprogram

I actually just ran into this myself, and finally understand what @dgryski was saying.

If nothing has has yet called the _start() function then the runtime is not yet initialized. So WASI programs that do everything from their init() function can run into this if they try to do anything outside the main goroutine.

Here is another example of the same problem https://github.com/fermyon/spin/issues/1259#issuecomment-1466551516

I tried the naive solution of just adding a call to _start() from the init() function here https://github.com/tinygo-org/tinygo/blob/dev/src/runtime/runtime_wasm_wasi.go#L30 but that did not appear to have any effect.

@dgryski @aykevl or anyone else, what do you think we can do about this?

deadprogram avatar Nov 12 '23 14:11 deadprogram

If nothing has has yet called the _start() function then the runtime is not yet initialized. So WASI programs that do everything from their init() function can run into this if they try to do anything outside the main goroutine.

It's much bigger than that. If _start isn't called, the runtime isn't initialized. This means the heap isn't set up, and most init functions haven't been run. Anything that does a heap allocation might crash. Or, indeed, interacts with the scheduler in any way. You really have to call _start first before calling any exported functions.

I tried the naive solution of just adding a call to _start() from the init() function here https://github.com/tinygo-org/tinygo/blob/dev/src/runtime/runtime_wasm_wasi.go#L30 but that did not appear to have any effect.

No that can't work. _start initializes the runtime, runs package initializers, and calls main. So even if _start was called, you would have introduced infinite recursion.

aykevl avatar Nov 14 '23 22:11 aykevl

Should we come up with some supported way to initialize the runtime so that this kind of behaviour is supported?

dgryski avatar Nov 15 '23 18:11 dgryski

Should we come up with some supported way to initialize the runtime so that this kind of behaviour is supported?

That would be very helpful!

deadprogram avatar Nov 26 '23 08:11 deadprogram