go-python / go-python/gopy

Returning string from Python callback to Go - and PyBytes_AsString() SIGSEGV

Abierto
#366 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Go
Estrellas
2.3k
Forks
136
Merge medio
14 min
PR fusionados (30 d)
2

Descripción

Hi,

Thanks for the great tool!

# Description

Trying to return a string from Python callback to Go - and getting SIGSEGV:

```
> python test.py
fs.CallBack(22, cbfun)...
in python cbfun: FieldI: 42 FieldS: str field ival: 22 sval: str field
fs.CallBackIf(22, cbfunif)...
in python cbfunif: FieldI: 42 FieldS: str field ival: 22 ifval: str field
fs.CallBackRval(22, cbfunrval)...
in python cbfunrval: FieldI: 42 FieldS: str field ival: 22 ifval: str field
```
(nothing more in output, literally)

Gdb shows more:

```
(gdb) back
#0 0x000055b7519d2627 in PyErr_Format ()
#1 0x000055b7519003a6 in ?? ()
#2 0x00007f330e0d0dab in _cgo_86d28a1f6e85_Cfunc_PyBytes_AsString () from /app/out/_funcs.cpython-310-x86_64-linux-gnu.so
#3 0x00007f330e098c41 in runtime.asmcgocall () at /usr/local/go/src/runtime/asm_amd64.s:923
#4 0x000000c000006700 in ?? ()
#5 0x00007ffee5d3e9a0 in ?? ()
#6 0x000055b763a8eee0 in ?? ()
#7 0x000000c000044008 in ?? ()
#8 0x00007ffee5d3ea58 in ?? ()
#9 0x00007f330e0a0c21 in crosscall2 () at /usr/local/go/src/runtime/cgo/asm_amd64.s:43
#10 0x00007f330e0d0c07 in funcs_FunStruct_CallBackRval () from /app/out/_funcs.cpython-310-x86_64-linux-gnu.so
#11 0x00007f330e0d5176 in _wrap__funcs_funcs_FunStruct_CallBackRval () from /app/out/_funcs.cpython-310-x86_64-linux-gnu.so
#12 0x000055b7519cbdae in ?? ()
#13 0x000055b7519c252b in _PyObject_MakeTpCall ()
#14 0x000055b7519bb16b in _PyEval_EvalFrameDefault ()
#15 0x000055b7519cc6ac in _PyFunction_Vectorcall ()
#16 0x000055b7519b4b2b in _PyEval_EvalFrameDefault ()
#17 0x000055b7519b1096 in ?? ()
#18 0x000055b751aa6f66 in PyEval_EvalCode ()
#19 0x000055b751ad1e98 in ?? ()
#20 0x000055b751acb79b in ?? ()
#21 0x000055b751ad1be5 in ?? ()
#22 0x000055b751ad10c8 in _PyRun_SimpleFileObject ()
#23 0x000055b751ad0d13 in _PyRun_AnyFileObject ()
#24 0x000055b751ac370e in Py_RunMain ()
#25 0x000055b751a99dfd in Py_BytesMain ()
#26 0x00007f330e733d90 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#27 0x00007f330e733e40 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#28 0x000055b751a99cf5 in _start ()
```

Trying _examples/funcs/
Just 2 changes to ret type string:

funcs.go:
```
-func (fs *FunStruct) CallBackRval(i int, fun func(fs *FunStruct, i int, v interface{}) bool) {
+func (fs *FunStruct) CallBackRval(i int, fun func(fs *FunStruct, i int, v interface{}) string) {
```

test.py:
```
in def cbfunrval(afs, ival, ifval):
- return True
+ return "some string"
```

# Versions
Gopy:
commit 1d7f3a2d29bd9f3921ff640f8e4e8908170ff3bf (HEAD -> master, tag: v0.4.10, origin/master, origin/HEAD)

Python 3.10.12 (main, Jul 29 2024, 16:56:48) [GCC 11.4.0] on linux
go version go1.23.2 linux/amd64

# The Reason
Generated out/funcs.go:

funcs_FunStruct_CallBackRval is generated to pass _fcret without type checks:
```
...
_fcret := C.PyObject_CallObject(_fun_arg, _fcargs)
C.gopy_decref(_fcargs)
C.gopy_err_handle()
C.PyGILState_Release(_gstate)
return C.GoString(C.PyBytes_AsString(_fcret))
...
```

And PyBytes_AsString - panics as _fcret is not bytes.

# Workaround

But, changing ret type to bytes - and things work fine:
test.py:
```
in def cbfunrval(afs, ival, ifval):
- return "some string"
+ return b"some string"
```

```
> python test.py
fs.CallBack(22, cbfun)...
in python cbfun: FieldI: 42 FieldS: str field ival: 22 sval: str field
fs.CallBackIf(22, cbfunif)...
in python cbfunif: FieldI: 42 FieldS: str field ival: 22 ifval: str field
fs.CallBackRval(22, cbfunrval)...
in python cbfunrval: FieldI: 42 FieldS: str field ival: 22 ifval: str field
got return value: some string
fs.CallBack(32, cls.ClassFun)...
in python class fun: FieldI: 42 FieldS: str field ival: 32 sval: str field
cls.CallSelf...
in python class fun: FieldI: 42 FieldS: str field ival: 77 sval: str field
fs.ObjArg with nil
got nil
fs.ObjArg with fs
ofs FieldI: 42 FieldS: str field
OK
```

# Fix
So, need to test-cover PyBytes_AsString calls with more types.

# Thank you!

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.