I have a project that was running fine until some updates happened (MacOS and rustc). Some calls to a library written in C (called from Rust) result in a segmentation fault:
println!("TEST");
unsafe { some_C_func(); }
The output is four times "TEST", but none of the printf's in some_C_func are actually invoked after the println! (Rust) is invoked four times (even though it is written once) the program aborts with a segmentation fault; it is as if the C function was never called.
My best bet is either incompatibilities between toolchains (although that seems like a stretch). Otherwise I would think perhaps Undefined Behaviour in Rust could cause this?
I am looking for possible issues that could cause something like this to happen.
window.h:
void* window_window(void*);
window.c:
// takes a pointer to a struct defined in this library
void* window_window(void* ptr) {
printf("WINDOW IN C\n");
return ((Window) ptr)->glfwWindow; // return a value of type *GLFWWindow
}
The Rust project contains a build script that generates rust bindings given window.h (using bindgen)
so in rust the mapping looks like:
extern "C" {
fn window_window(arg1: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void;
}
This code is then called from an implemention on a struct:
struct Window {
ptr: *mut ::std::os::raw::c_void,
}
impl Window {
fn window(&self) -> *mut ::std::os::raw::c_void {
println!("WINDOW");
unsafe {
window_window(self.ptr)
}
}
}
The output (upon calling Window::window once) is
WINDOW
WINDOW
WINDOW
WINDOW
zsh: segmentation fault cargo run
The C library links to (all static) GLFW, metal, and cocoa, Dear Imgui. They are linked (or compiled into, in case of ImGui) into a dynamic library.
the problem also occurs with a similar function which returns int (instead of a pointer) and is named window_update.
MacOS Senoma 14.5 The old rust version I cannot find, the new version is the latest: stable-aarch64-apple-darwin (rustc 1.82.0).
Rust projects are assembled using cargo, for C I use XCode (for any metal related programming) and CMake.
The problem is indeed a double definition. Within the library the same function is defined twice (window_window in this case).
More specifically it was defined within a C library as shown above, but also within the rust project as follows:
#[no_mangle]
unsafe extern "C" fn window_window(handle: *const ()) -> bool {
println!("THIS IS NOT GOOD");
/* snip */
}
The #[no_mangle] attribute makes it so the name is preserved in the binary, hence there are two definitions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With