Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation fault disappears after renaming a function

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.

reproducible example

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.

like image 678
Plegeus Avatar asked Jan 18 '26 08:01

Plegeus


1 Answers

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.

like image 160
Plegeus Avatar answered Jan 21 '26 00:01

Plegeus