-
Notifications
You must be signed in to change notification settings - Fork 271
Open
Description
Edit: The solution is to make the trait being passed as Arc<dyn T>
foreign. Keeping the issue open because a better error message would be nice
I have defined the following Object
#[derive(uniffi::Object, Clone)]
pub struct ABIDynamicArray {
element_type: Arc<dyn ABIType>,
}
impl FfiToRustABIType for ABIDynamicArray {
fn to_rust_abi_type(&self) -> RustABIType {
eprintln!("DEBUGPRINT[43]: dynamic_array.rs:34 (before let cloned = self.clone();)");
let cloned = self.clone();
eprintln!("DEBUGPRINT[44]: dynamic_array.rs:35 (after let cloned = self.clone();)");
eprintln!("DEBUGPRINT[46]: dynamic_array.rs:38 (before cloned.into())");
let res = cloned.into();
eprintln!("DEBUGPRINT[47]: dynamic_array.rs:39 (after cloned.into())");
res
}
}
#[uniffi::export]
impl ABIType for ABIDynamicArray {
fn decoode(&self, data: &[u8]) -> ABIValue {
let rust_abi_type = self.to_rust_abi_type();
ABIValue::from(rust_abi_type.decode(data).unwrap())
}
fn encode(&self, value: ABIValue) -> Vec<u8> {
let rust_abi_type = self.to_rust_abi_type();
rust_abi_type.encode(&value.into()).unwrap()
}
}
#[uniffi::export]
impl ABIDynamicArray {
#[uniffi::constructor]
pub fn new(element_type: Arc<dyn ABIType>) -> Self {
ABIDynamicArray { element_type }
}
}
Attempting to use the python bindings:
def test_abi_bool_array():
abi_arr = AbiDynamicArray(element_type=AbiBool())
arr = AbiValue(array=[AbiValue(bool=True)])
encoded = abi_arr.encode(arr)
assert encoded == b'\x000180'
I get the following segfault. One strange thing to note us that sometimes it segfaults on self.clone()
and sometimes it segfaults on cloned.into()
. This seems like a problem with erroneously dropping a reference in the binding somewhere in a non-deterministic way.
lldb -- "$(poetry run which python)" -X dev -m pytest -s -k array
(lldb) target create "/Users/joe/git/algorandfoundation/algokit-core/packages/python/algokit_uti
ls/.venv/bin/python"
Current executable set to '/Users/joe/git/algorandfoundation/algokit-core/packages/python/algoki
t_utils/.venv/bin/python' (arm64).
(lldb) settings set -- target.run-args "-X" "dev" "-m" "pytest" "-s" "-k" "array"
(lldb) run
Process 7124 launched: '/Users/joe/git/algorandfoundation/algokit-core/packages/python/algokit_u
tils/.venv/bin/python' (arm64)
/Users/joe/git/algorandfoundation/algokit-core/packages/python/algokit_utils/.venv/lib/python3.1
3/site-packages/pytest_asyncio/plugin.py:211: PytestDeprecationWarning: The configuration option
"asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future
versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function sc
ope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the
future. Valid fixture loop scopes are: "function", "class", "module", "package", "session"
warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))
============================= test session starts ==============================
platform darwin -- Python 3.13.2, pytest-8.4.1, pluggy-1.6.0
rootdir: /Users/joe/git/algorandfoundation/algokit-core/packages/python/algokit_utils
configfile: pyproject.toml
plugins: asyncio-1.1.0
asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_sc
ope=function
collected 3 items / 2 deselected / 1 selected
tests/test_utils.py DEBUGPRINT[43]: dynamic_array.rs:34 (before let cloned = self.clone();)
Process 7124 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000102d3e37c libalgokit_utils_ffi.dylib`_$LT$algokit_utils_ffi..abi..abi_typ
e..dynamic_array..ABIDynamicArray$u20$as$u20$algokit_utils_ffi..abi..abi_type..FfiToRustABIType$
GT$::to_rust_abi_type::h7cd0d5bd89393e60 + 68
libalgokit_utils_ffi.dylib`_$LT$algokit_utils_ffi..abi..abi_type..dynamic_array..ABIDynamicArray
$u20$as$u20$algokit_utils_ffi..abi..abi_type..FfiToRustABIType$GT$::to_rust_abi_type::h7cd0d5bd8
9393e60:
-> 0x102d3e37c <+68>: ldadd x22, x8, [x20]
0x102d3e380 <+72>: tbnz x8, #0x3f, 0x102d3e3d0 ; <+152>
0x102d3e384 <+76>: ldr x21, [x21, #0x8]
0x102d3e388 <+80>: stp x20, x21, [sp]
Target 0: (python) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x0000000102d3e37c libalgokit_utils_ffi.dylib`_$LT$algokit_utils_ffi..abi..abi_typ
e..dynamic_array..ABIDynamicArray$u20$as$u20$algokit_utils_ffi..abi..abi_type..FfiToRustABIType$
GT$::to_rust_abi_type::h7cd0d5bd89393e60 + 68
frame #1: 0x0000000102d3edec libalgokit_utils_ffi.dylib`_$LT$algokit_utils_ffi..abi..abi_typ
e..dynamic_array..ABIDynamicArray$u20$as$u20$algokit_utils_ffi..abi..abi_type..ABIType$GT$::enco
de::h000991ce3b96c180 + 36
frame #2: 0x0000000102d22628 libalgokit_utils_ffi.dylib`uniffi_core::ffi::rustcalls::rust_ca
ll::h521bb2588921a417 + 412
frame #3: 0x0000000102d3f018 libalgokit_utils_ffi.dylib`uniffi_algokit_utils_ffi_fn_method_a
bidynamicarray_encode + 44
frame #4: 0x00000001016c0050 libpython3.13.dylib`ffi_call_SYSV + 80
frame #5: 0x00000001016beae4 libpython3.13.dylib`ffi_call_int + 1452
frame #6: 0x00000001016be52c libpython3.13.dylib`ffi_call + 52
frame #7: 0x0000000101d27620 libpython3.13.dylib`_call_function_pointer + 248
frame #8: 0x0000000101d27194 libpython3.13.dylib`_ctypes_callproc + 724
frame #9: 0x0000000101d24768 libpython3.13.dylib`PyCFuncPtr_call + 332
frame #10: 0x000000010137760c libpython3.13.dylib`_PyEval_EvalFrameDefault + 55044
frame #11: 0x0000000101466d84 libpython3.13.dylib`_PyObject_Call_Prepend + 296
frame #12: 0x0000000101466798 libpython3.13.dylib`slot_tp_call + 216
frame #13: 0x000000010137985c libpython3.13.dylib`_PyEval_EvalFrameDefault + 63828
frame #14: 0x0000000101466d84 libpython3.13.dylib`_PyObject_Call_Prepend + 296
frame #15: 0x0000000101466798 libpython3.13.dylib`slot_tp_call + 216
frame #16: 0x000000010137760c libpython3.13.dylib`_PyEval_EvalFrameDefault + 55044
frame #17: 0x0000000101466d84 libpython3.13.dylib`_PyObject_Call_Prepend + 296
frame #18: 0x0000000101466798 libpython3.13.dylib`slot_tp_call + 216
frame #19: 0x000000010137985c libpython3.13.dylib`_PyEval_EvalFrameDefault + 63828
frame #20: 0x0000000101466d84 libpython3.13.dylib`_PyObject_Call_Prepend + 296
frame #21: 0x0000000101466798 libpython3.13.dylib`slot_tp_call + 216
frame #22: 0x000000010137985c libpython3.13.dylib`_PyEval_EvalFrameDefault + 63828
frame #23: 0x0000000101466d84 libpython3.13.dylib`_PyObject_Call_Prepend + 296
frame #24: 0x0000000101466798 libpython3.13.dylib`slot_tp_call + 216
frame #25: 0x000000010137985c libpython3.13.dylib`_PyEval_EvalFrameDefault + 63828
frame #26: 0x00000001014640c8 libpython3.13.dylib`PyEval_EvalCode + 132
frame #27: 0x0000000101463bd8 libpython3.13.dylib`builtin_exec + 388
frame #28: 0x0000000101600160 libpython3.13.dylib`cfunction_vectorcall_FASTCALL_KEYWORDS.llv
m.12452703498012727648 + 88
frame #29: 0x0000000101374908 libpython3.13.dylib`_PyEval_EvalFrameDefault + 43520
frame #30: 0x000000010154edcc libpython3.13.dylib`pymain_run_module + 232
frame #31: 0x000000010154dfc4 libpython3.13.dylib`Py_RunMain + 488
frame #32: 0x00000001014a758c libpython3.13.dylib`pymain_main + 468
frame #33: 0x00000001014a73ac libpython3.13.dylib`Py_BytesMain + 36
frame #34: 0x0000000190582b98 dyld`start + 6076
(lldb)
Metadata
Metadata
Assignees
Labels
No labels