SIGSEGV when passing *const c_char to bindgen function

So I am wrapping bindgen generated unsafe wrappers for a C library (in this case EFL) with safe Rust. Currently, I am stuck facing a SIGSEGV (Address boundary error) when attempting to pass *const c_char from the libc crate. Currently, my code looks like this:

pub fn win_util_standard_add(name: &str, title: &str) -> *mut Evas_Object {
    let cname = std::ffi::CString::new(name).expect("CString::new() failed");
    let cname_ptr: *const c_char = cname.as_ptr();
    let ctitle = std::ffi::CString::new(title).expect("CString::new() failed");
    let ctitle_ptr: *const c_char = ctitle.as_ptr();

    unsafe { efl_sys::elm_win_util_standard_add(cname_ptr, ctitle_ptr) }
}

efl_sys::elm_win_util_standard_add() takes two *const c_chars. What am I doing wrong?

I am very new to working with unsafe Rust and ffi in general, so please excuse my confusion.

Obligatory Repository

One possibility is that the owned variables (cname and ctitle) are being dropped on the Rust side, meaning their memory is freed, while the pointers (cname_ptr and ctitle_ptr) are still being used on the C side. You could try leaking them to see if that fixes it, as a test.

Thank you for the response. I edited the code to add:

std::mem::forget(cname);
std::mem::forget(ctitle);

before returning the result of the unsafe block, but that still results in the same error.

Edit:

I tried leaking different parts of my program to see if the error was actually in something else. It turns out that the issue was in:

pub fn init() {
    let args = std::env::args()
        .map(|arg| CString::new(arg).unwrap())
        .collect::<Vec<CString>>();
    let c_args = args
        .iter()
        .map(|arg| arg.as_ptr())
        .collect::<Vec<*const c_char>>();

    unsafe { efl_sys::elm_init(c_args.len() as c_int, c_args.as_ptr() as *mut *mut c_char) };
}

where the function was dropping the args and c_args while the C function still had the pointers to them.

1 Like

Great, glad you found it.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.