-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UB at GDNative termination (seen during integration tests) #894
Comments
Thanks for the report, and for narrowing it down!
Can you describe the exact circumstances that caused this?
It's a real pity we can't use miri. FFI is a ticking time bomb. |
I am currently investigating the bug. |
Instance::maybe_emplace()
causes undefined behavior.Instance::maybe_emplace()
causes memory leak.
Instance::maybe_emplace()
causes memory leak.Instance::maybe_emplace()
causes undefined behavior and memory leak.
It could be quite hard to consistently reproduce this... Ideally we find some minimal code (simple godot-rust entry point + one We can also use CI, I'll gladly help a dedicated Windows config in GitHub action to run/test such a minimal example.
What do you mean? This is a highly unsafe pointer cast for sure. But is it the line that caused the segfault for you? |
What I have done so far:
Edit: I tried my best but it didn't work. |
I think this might not be related to For context:
While it wasn't a big issue in Godot 3.4, it seems to show up again for the Godot 3.5 RCs on Windows. If someone has the time to confirm/reproduce or even help debugging this, that would be greatly appreciated. |
Instance::maybe_emplace()
causes undefined behavior and memory leak.
You could assign this to me if you want since I'm already familiar with the issue in 3.x. I should be able to look at it this week |
@Waridley Thank you very much, that's greatly appreciated! ❤️ |
Not sure if it's related, but I'm getting a consistent segfault here: https://github.com/godot-rust/godot-rust/blob/1b4754ca073e97242d3cf8d26afd865af889a344/test/src/lib.rs#L227 It's like the GodotString created from {
let foo = Reference::new().into_shared();
let foo = unsafe { foo.assume_safe() };
foo.set_meta("foo", "bar");
instance_id = foo.get_instance_id();
assert!(unsafe { Node::try_from_instance_id(instance_id).is_none() });
let reconstructed = unsafe { Reference::from_instance_id(instance_id) };
let key2 = GodotString::from("foo");
let val = reconstructed.get_meta(key2);
assert_eq!(
"bar",
String::from_variant(&val).unwrap()
);
let _SEGFAULT = reconstructed.get_meta("foo");
} |
Maybe the compiler is optimizing #[doc(hidden)]
#[inline(never)]
pub(crate) unsafe fn icallptr_var_str(
method_bind: *mut sys::godot_method_bind,
obj_ptr: *mut sys::godot_object,
arg0: GodotString,
) -> sys::godot_variant {
let gd_api = get_api();
let mut argument_buffer: [*const libc::c_void; 1usize] = [arg0.sys() as *const _ as *const _];
let mut ret = sys::godot_variant::default();
let ret_ptr = (&mut ret) as *mut _;
(gd_api.godot_method_bind_ptrcall)(
method_bind,
obj_ptr,
argument_buffer.as_mut_ptr() as *mut _,
ret_ptr as *mut _,
);
drop(arg0);
ret
} |
Confirmed, using |
924: use ManuallyDrop in ptrcalls to prevent drop reordering r=Bromeon a=Waridley On rustc 1.65.0-nightly (29e4a9ee0 2022-08-10), drops of args in some ptrcalls are seemingly being reordered to before the FFI call. Using `ManuallyDrop` prevents this. This could potentially be related to #894, but I'm not confident enough to say it will definitely fix it yet. Co-authored-by: Waridley <[email protected]>
Going to optimistically close this. |
Issue Codes:
https://github.com/godot-rust/godot-rust/blob/25603b047364cde1ab1267cb41579a2734ab01d5/gdnative-core/src/object/instance.rs#L104-L209
Reference Information:
#891 (comment)
The text was updated successfully, but these errors were encountered: