Browse Source

runner.go: Don't cast a Go handle to a C void *

Cgo handles passing pointers through C to another Go function
with integer handles to the Go memory. However, it is not legal
to cast this handle to a void * aux data in C. Doing this results
in panics about invalid pointers on the stack in certain
circumstances.

Instead, we should pass a pointer to the handle and pin that in
memory. It would probably also be safe to directly pin the Go
function pointer and pass that rather than using the handle since
it is an opaque blob to C. However, using a handle is the more
generally correct solution and there is no need to get clever.
Jesse Gross 8 months ago
parent
commit
c989321509
1 changed files with 6 additions and 2 deletions
  1. 6 2
      llama/llama.go

+ 6 - 2
llama/llama.go

@@ -163,7 +163,7 @@ type ModelParams struct {
 
 
 //export llamaProgressCallback
 //export llamaProgressCallback
 func llamaProgressCallback(progress C.float, userData unsafe.Pointer) C.bool {
 func llamaProgressCallback(progress C.float, userData unsafe.Pointer) C.bool {
-	handle := cgo.Handle(userData)
+	handle := *(*cgo.Handle)(userData)
 	callback := handle.Value().(func(float32))
 	callback := handle.Value().(func(float32))
 	callback(float32(progress))
 	callback(float32(progress))
 	return true
 	return true
@@ -190,8 +190,12 @@ func LoadModelFromFile(modelPath string, params ModelParams) *Model {
 		handle := cgo.NewHandle(params.Progress)
 		handle := cgo.NewHandle(params.Progress)
 		defer handle.Delete()
 		defer handle.Delete()
 
 
+		var handlePin runtime.Pinner
+		handlePin.Pin(&handle)
+		defer handlePin.Unpin()
+
 		cparams.progress_callback = C.llama_progress_callback(C.llamaProgressCallback)
 		cparams.progress_callback = C.llama_progress_callback(C.llamaProgressCallback)
-		cparams.progress_callback_user_data = unsafe.Pointer(handle)
+		cparams.progress_callback_user_data = unsafe.Pointer(&handle)
 	}
 	}
 
 
 	return &Model{c: C.llama_load_model_from_file(C.CString(modelPath), cparams)}
 	return &Model{c: C.llama_load_model_from_file(C.CString(modelPath), cparams)}