std::ffi::CString segmentation fault


I met a strange CString behavior.
When I call
let source: CString = CString::new("1234567").unwrap();
I get Segmentation Fault 11

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

But it works when I do
let source: CString = CString::new("12345678").unwrap();
or pass any string with 8 characters at least.


Are you sure you’re not using source.as_ptr() value outside scope of the variable anywhere? The temporary validity of the pointer is the common source of crashes here.


@kornel I call as_ptr() before, in other function scope and for other variable.

fn foo() {
    let source: CString = CString::new("
        multiple line string
    let srcptr = source.as_ptr();
    bar(srcptr, source.as_bytes().len()); // unsafe block

fn main() {
    let source: CString = CString::new("1234567").unwrap(); // SegFault here


This smells of corruption somewhere. What does bar() do/look like?


@vitalyd Well, this is kind of opengl stuff.

fn bar(....) -> .... {
    unsafe {
        gl.ShaderSource(shader, 1, &source, &len);
I didn’t find other way to pass *const *const GLchar


Inside bar() I call from_raw() breaking the safety rule. I passed a pointer value that was generated by opengl function.
I switched to use String::from_raw_parts instead of CString and the problem has gone.

let mut log: [i8; 512] = [0; 512];
let log_ptr: *mut i8 = &mut log[0];
let length: *mut i32 = &mut 0;
gl.GetShaderInfoLog(shader, 512, length, log_ptr);
// let s = CString::from_raw(log_ptr);
let s = String::from_raw_parts(log_ptr as *mut u8, *length as usize, 512);
println!("{:?}", s);


Yeah, that would do it :slight_smile:. You’ve probably already seen it, but CStr can be used to view a C string without taking ownership of it (it’s basically the &str analog to Rust’s String, but for CString).


This may crash and cause corruption as well, because Rust will try to free String's pointer using its jemalloc, and you’re using stack-allocated object here.

String::from_raw_parts is a risky hack that you shouldn’t normally need, and it’s probably unsafe to use with anything other than another String or Vec’s raw parts, carefully taken.