Open lynnux opened 6 years ago
Built OK, but crash when running, stack (from x64dbg with symbols):
Address To From Size Comment Party
003D8AD0 0162F563 01647DAB 14 t.nk_buffer_init+9B User
003D8AE4 015147B5 0162F563 7660 t.nk_init+53 User
003E0144 0146B35A 015147B5 7758 t.nuklear_rust::NkContext::new+65 User
003E789C 0143F041 0146B35A 81CC t.nuklear_backend_gdi::bundle+25A User
003EFA68 016273FC 0143F041 34 t.t::main+B1 User
003EFA9C 01626527 016273FC 68 t.panic_unwind::__rust_maybe_catch_panic+3C User
003EFB04 01445062 01626527 14 t.std::rt::lang_start+F7 User
003EFB18 0166E645 01445062 40 t.main+22 User
003EFB58 76B4336A 0166E645 C t._tmainCRTStartup+FD System
003EFB64 77D19902 76B4336A 40 kernel32.BaseThreadInitThunk+E System
003EFBA4 77D198D5 77D19902 18 ntdll.__RtlUserThreadStart+70 System
003EFBBC 00000000 77D198D5 ntdll._RtlUserThreadStart+1B User
Seems corresponding C code is:
NK_API void
nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a,
nk_size initial_size)
{
NK_ASSERT(b);
NK_ASSERT(a);
NK_ASSERT(initial_size);
if (!b || !a || !initial_size) return;
nk_zero(b, sizeof(*b));
b->type = NK_BUFFER_DYNAMIC;
b->memory.ptr = a->alloc(a->userdata,0, initial_size); ----------- crash here, the a->alloc is 0
b->memory.size = initial_size;
b->size = initial_size;
b->grow_factor = 2.0f;
b->pool = *a;
}
and nk_allocator
defined in rust as:
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nk_allocator {
pub userdata: nk_handle,
pub alloc: nk_plugin_alloc,
pub free: nk_plugin_free,
}
the nk_handle is defined as:
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct nk_handle {
pub ptr: __BindgenUnionField<*mut ::std::os::raw::c_void>,
pub id: __BindgenUnionField<::std::os::raw::c_int>,
pub bindgen_union_field: u64,
}
but nk_handle
defined in C is : typedef union {void *ptr; int id;} nk_handle;
, when built by i686 toolchain, is should take only 4 bytes same as u32, so this maybe the reason. And I temporary modified the struct in the cargo source as follow:
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct nk_handle {
pub ptr: __BindgenUnionField<*mut ::std::os::raw::c_void>,
pub id: __BindgenUnionField<::std::os::raw::c_int>,
pub bindgen_union_field: u32,
}
It works OK built by i686 toolchain!
Thanks for the investigation! Dropped another fix, please try it. https://github.com/snuk182/nuklear-rust/commit/20ee23e9340a4cf5ac61862dfe60198de279eb77 https://crates.io/crates/nuklear-rust/0.3.2
still crash, but let nk_style_item_data
use u64 will be OK.
pub struct nk_image {
pub handle: nk_handle, // 4 bytes
pub w: ::std::os::raw::c_ushort, // 2 bytes
pub h: ::std::os::raw::c_ushort, // 2 bytes
pub region: [::std::os::raw::c_ushort; 4usize], // 8 bytes
}
on i686 it's at least use 4+2+2+8=16
pub struct nk_style_item_data {
pub image: __BindgenUnionField<nk_image>,
pub color: __BindgenUnionField<nk_color>,
pub bindgen_union_field: [usize; 3usize], // on i686, 4*3 = 12 not enough
}
don't know how bindgen generate these code, maybe there a portable way to generate code support both i686 and x86_64?
While untagged unions are not supported in stable, bindgen makes them with sorta illegal and unsafe way. When I have more time to dig into that, I will check it closer. So far I removed the two other usize
's.
Seems https://github.com/snuk182/nuklear-test/tree/gdi depends this library. Works great using
nightly-x86_64-pc-windows-msvc
, but after switched tonightly-i686-pc-windows-msvc
, I got these errors: