Skip to content

Commit

Permalink
Merge pull request #333 from gzigzigzeo/master
Browse files Browse the repository at this point in the history
Fixes go GC crash on trap
  • Loading branch information
syrusakbary authored Sep 21, 2022
2 parents 4c4b374 + 32e79da commit 74dd6b9
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 26 deletions.
6 changes: 6 additions & 0 deletions examples/example_early_exit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package wasmer

import (
"fmt"
"runtime"

"github.com/wasmerio/wasmer-go/wasmer"
)

Expand Down Expand Up @@ -101,6 +103,10 @@ func ExampleFunction_Call() {

fmt.Println("Exited early with:", err)

// These lines are here to ensure that SetFinalizer works correctly
runtime.GC()
runtime.GC()

// Output:
// Compiling module...
// Instantiating module...
Expand Down
2 changes: 1 addition & 1 deletion wasmer/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type TrapError struct {
}

func newErrorFromTrap(pointer *C.wasm_trap_t) *TrapError {
trap := newTrap(pointer, nil)
trap := newTrapFromPointer(pointer, nil)

return &TrapError{
message: trap.Message(),
Expand Down
14 changes: 4 additions & 10 deletions wasmer/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,8 @@ func function_trampoline(env unsafe.Pointer, args *C.wasm_val_vec_t, res *C.wasm
results, err := (function)(arguments)

if err != nil {
trap := NewTrap(hostFunction.store, err.Error())

runtime.KeepAlive(trap)

return trap.inner()
pointer := newWasmTrap(hostFunction.store, err.Error())
return pointer
}

toValueVec(results, res)
Expand Down Expand Up @@ -191,11 +188,8 @@ func function_with_environment_trampoline(env unsafe.Pointer, args *C.wasm_val_v
results, err := (function)(hostFunction.userEnvironment, arguments)

if err != nil {
trap := NewTrap(hostFunction.store, err.Error())

runtime.KeepAlive(trap)

return trap.inner()
pointer := newWasmTrap(hostFunction.store, err.Error())
return pointer
}

toValueVec(results, res)
Expand Down
41 changes: 26 additions & 15 deletions wasmer/trap.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,34 @@ type Trap struct {
_ownedBy interface{}
}

func newTrap(pointer *C.wasm_trap_t, ownedBy interface{}) *Trap {
// newWasmTrap creates C wasm_trap structure and returns it's pointer
func newWasmTrap(store *Store, message string) *C.wasm_trap_t {
messageBytes := []byte(message)
var bytesPointer *C.uint8_t
bytesLength := len(messageBytes)

if bytesLength > 0 {
bytesPointer = (*C.uint8_t)(unsafe.Pointer(&messageBytes[0]))
}

runtime.KeepAlive(store)
runtime.KeepAlive(message)

return C.to_wasm_trap_new(store.inner(), bytesPointer, C.size_t(bytesLength))
}

// newTrapFromPonter creates Trap from C.wasm_trap structure and attaches GC finalizer for it
func newTrapFromPointer(pointer *C.wasm_trap_t, ownedBy interface{}) *Trap {
trap := &Trap{
_inner: pointer,
_ownedBy: ownedBy,
}

return trapWithFinalizer(trap, ownedBy)
}

// trapWithFinalizer attaches GC finalizer to the trap
func trapWithFinalizer(trap *Trap, ownedBy interface{}) *Trap {
if ownedBy == nil {
runtime.SetFinalizer(trap, func(trap *Trap) {
inner := trap.inner()
Expand All @@ -49,20 +71,9 @@ func newTrap(pointer *C.wasm_trap_t, ownedBy interface{}) *Trap {
// store := wasmer.NewStore(engine)
// trap := NewTrap(store, "oops")
func NewTrap(store *Store, message string) *Trap {
messageBytes := []byte(message)
var bytesPointer *C.uint8_t
bytesLength := len(messageBytes)

if bytesLength > 0 {
bytesPointer = (*C.uint8_t)(unsafe.Pointer(&messageBytes[0]))
}

trap := C.to_wasm_trap_new(store.inner(), bytesPointer, C.size_t(bytesLength))

runtime.KeepAlive(store)
runtime.KeepAlive(message)

return newTrap(trap, nil)
pointer := newWasmTrap(store, message)
trap := &Trap{_inner: pointer}
return trapWithFinalizer(trap, nil)
}

func (self *Trap) inner() *C.wasm_trap_t {
Expand Down

0 comments on commit 74dd6b9

Please sign in to comment.