Forráskód Böngészése

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 hónapja
szülő
commit
c989321509
1 módosított fájl, 6 hozzáadás és 2 törlés
  1. 6 2
      llama/llama.go

+ 6 - 2
llama/llama.go

@@ -163,7 +163,7 @@ type ModelParams struct {
 
 //export llamaProgressCallback
 func llamaProgressCallback(progress C.float, userData unsafe.Pointer) C.bool {
-	handle := cgo.Handle(userData)
+	handle := *(*cgo.Handle)(userData)
 	callback := handle.Value().(func(float32))
 	callback(float32(progress))
 	return true
@@ -190,8 +190,12 @@ func LoadModelFromFile(modelPath string, params ModelParams) *Model {
 		handle := cgo.NewHandle(params.Progress)
 		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_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)}