更新MacOS与rustc后,Rust调用C库函数出现段错误及重复输出
调用C库函数出现段错误的问题排查
问题描述
原本运行正常的项目,在MacOS和rustc更新后,调用C编写的库函数时出现段错误。例如执行以下代码:
println!("TEST"); unsafe { some_C_func(); }
程序会输出四次"TEST",但C函数内的printf从未执行,四次输出后直接因段错误终止,仿佛C函数根本没被调用。怀疑是工具链不兼容或Rust中存在未定义行为,寻求问题原因。
可复现示例
C库代码
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 }
Rust代码
通过bindgen基于window.h生成的绑定:
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、Dear ImGui,编译为动态库。返回int类型的window_update函数也存在类似问题。
环境信息
- MacOS Sonoma 14.5
- rustc 1.82.0(stable-aarch64-apple-darwin)
- Rust项目使用cargo构建,C库使用XCode和CMake构建
可能的问题原因
- 工具链ABI不兼容:MacOS和rustc更新后,C工具链(XCode/CMake的clang版本)与Rust工具链的ABI出现差异,包括函数调用约定、内存布局、目标架构匹配度等,导致函数调用时出现异常。
- 动态库加载异常:MacOS对动态库的签名、加载路径有严格限制,系统更新后可能出现库加载失败或符号解析错误,导致调用时跳转到无效内存地址,直接触发段错误。
- 无效指针传递:
self.ptr可能是未初始化、已释放或类型转换错误的无效指针。段错误可能发生在C函数执行前的栈准备或指针解引用阶段,导致C函数根本没机会执行。 - 静态链接库符号冲突:C库静态链接的GLFW等依赖,与Rust项目间接引入的同库不同版本发生符号冲突,更新后符号解析顺序变化,导致调用到错误的函数实现。
- 堆栈对齐问题:aarch64架构对堆栈对齐要求严格,Rust和C编译器的堆栈对齐规则在更新后出现不一致,调用C函数时堆栈未正确对齐,触发硬件异常。
内容的提问来源于stack exchange,提问作者Plegeus
相关产品推荐
相关产品推荐

