重命名函数后分段错误消失

问题描述 投票:0回答:1

我有一个项目运行良好,直到发生一些更新(MacOS 和 rustc)。 对用 C 编写的库(从 Rust 调用)的某些调用会导致分段错误:

println!("TEST");
unsafe { some_C_func(); }

输出是“TEST”的四倍,但是 some_C_func 中的 printf 在 println! 之后实际上没有被调用! (Rust) 被调用四次(即使只写入一次)程序因分段错误而中止;就好像 C 函数从未被调用过。

我最好的选择是工具链之间不兼容(尽管这看起来有些牵强)。否则我会认为 Rust 中的未定义行为可能会导致这种情况?

我正在寻找可能导致此类情况发生的问题。

可重现的示例

窗口.h:

void* window_window(void*);

窗口.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
}

Rust 项目包含一个构建脚本,该脚本可根据给定的 window.h(使用 bindgen)生成 Rust 绑定

所以在 Rust 中映射看起来像这样:

extern "C" {
  fn window_window(arg1: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void;
}

然后从结构体的实现中调用此代码:

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)
    }
  }
}

输出(调用 Window::window 一次)是

WINDOW
WINDOW
WINDOW
WINDOW
zsh: segmentation fault  cargo run

C 库链接到(全静态)GLFW、metal 和 cocoa,亲爱的 Imgui。它们被链接(或者编译到 ImGui 的情况下)到动态库中。

这个问题也出现在一个类似的函数上,该函数返回 int (而不是指针)并被命名为 window_update。

MacOS 塞诺玛 14.5 旧的 Rust 版本我找不到,新版本是最新的:stable-aarch64-apple-darwin (rustc 1.82.0)。

Rust 项目是使用 Cargo 组装的,对于 C,我使用 XCode(用于任何与金属相关的编程)和 CMake。

c rust segmentation-fault
1个回答
0
投票

问题确实是双重定义。 在库中,相同的函数定义了两次(在本例中为 window_window)。

更具体地说,它是在 C 库中定义的,如上所示,但也在 rust 项目中定义,如下所示:

    #[no_mangle]
    unsafe extern "C" fn window_window(handle: *const ()) -> bool {
      println!("THIS IS NOT GOOD");
      /* snip */
    }

#[no_mangle]
属性使得名称保留在二进制文件中,因此有两个定义。

© www.soinside.com 2019 - 2024. All rights reserved.