Rust中shm_open()调用返回-1失败,C实现正常,求排查建议
Hey there! Let's figure out why your Rust shm_open call is failing even though your equivalent C code works. I've run into similar FFI pitfalls before, so here are some targeted steps to debug this:
Key Issues to Check
Fix the dangling CString pointer
This is almost certainly the root cause in your code. When you writelet name = CString::new("/shaman").unwrap().as_ptr();, you create a temporaryCStringinstance, grab its pointer, and then immediately drop theCString(since it's not stored in a persistent variable). By the timeshm_openexecutes, the memory backing the string has been freed, leaving you with a dangling pointer. To fix this:// Store the CString in a variable to keep it alive during the shm_open call let c_name = CString::new("/shaman").unwrap(); let name = c_name.as_ptr();Get detailed error information from errno
A return value of -1 tells you something went wrong, but not what. Useerrnoandstrerrorto retrieve the actual error message—this will pinpoint whether it's a permission issue, existing shared memory object, or another problem. Add this after yourshm_opencall:if fd == -1 { unsafe { let err_code = errno(); let err_msg = CString::from_raw(strerror(err_code)) .into_string() .unwrap_or("Unknown error".to_string()); println!("shm_open failed: {}", err_msg); } }Verify flags and permissions match your C code
Double-check that your flags (O_CREAT | O_RDWR) and permissions (0o600) are identical to your working C implementation. For example, if your C code usesO_EXCLto fail if the object already exists, your Rust code should mirror that behavior.Check for existing shared memory objects
If/shamanalready exists and your C code handles this scenario differently (e.g., opening it withoutO_CREAT), your Rust code might be hitting an unexpected error. Try runningshm_unlink /shamanin your terminal to delete the existing object, then test your Rust code again.Ensure proper runtime privileges
On some systems, creating shared memory requires specific capabilities (likeCAP_IPC_LOCKon Linux). Since your C code works, this is less likely, but it's worth confirming your Rust binary is running with the same permissions as your C binary.
Corrected Example Code
Here's a revised version of your code incorporating the fixes above:
extern crate libc; use libc::{O_CREAT, O_RDWR, shm_open, errno, strerror}; use std::ffi::CString; fn shm_create() { // Preserve the CString to avoid dangling pointers let c_name = match CString::new("/shaman") { Ok(name) => name, Err(e) => { println!("Failed to create CString: {}", e); return; } }; let name = c_name.as_ptr(); let fd = unsafe { shm_open(name, O_CREAT | O_RDWR, 0o600) }; if fd == -1 { unsafe { let err_code = errno(); let err_msg = CString::from_raw(strerror(err_code)) .into_string() .unwrap_or_else(|_| "Unknown error".to_string()); println!("shm_open: -1, error: {}", err_msg); } } else { println!("shm_open: {}", fd); } } fn main() { shm_create(); }
Start with fixing the dangling pointer issue—it's the most common reason for this kind of failure when working with C FFI in Rust. Once that's resolved, the error message from errno should guide you if any other issues remain.
内容的提问来源于stack exchange,提问作者mik

