How do I free a *char allocated via FFI in Rust? -
i'm calling llvm api via rust's ffi. llvmprintmoduletostring
uses strdup create string. however, when wrap pointer in cstring
, error when rust drops it.
#![feature(cstr_memory)] use std::ffi::cstring; extern crate llvm_sys llvm; fn main() { let llvm_ir_cstring; unsafe { let module = llvm::core::llvmmodulecreatewithname(b"nop\0".as_ptr() *const _); let llvm_ir_char_ptr = llvm::core::llvmprintmoduletostring(module); llvm::core::llvmdisposemodule(module); llvm_ir_cstring = cstring::from_ptr(llvm_ir_char_ptr); } println!("llvm_ir_cstring: {:?}", llvm_ir_cstring); }
valgrind error:
==10413== invalid read of size 4 ==10413== @ 0x4870586: pthread_mutex_lock (in /usr/lib/libpthread-2.21.so) ==10413== 0x17f89b: je_arena_dalloc_small (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== 0x178c30: je_sdallocx (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== 0x10fa57: heap::imp::deallocate::h1fb92d59333c497bkja (heap.rs:268) ==10413== 0x10f999: heap::deallocate::h5680e3fedc9e96320da (heap.rs:89) ==10413== 0x10f929: heap::exchange_free::h452463f962f7ec23kfa (heap.rs:131) ==10413== 0x10f8c5: box$lt$$u5b$u8$u5d$$gt$::drop.1769::haf7017472635c7cf (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== 0x10f836: std..ffi..c_str..cstring::drop.1766::h04d2b3db8d468f0c (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== 0x10f5ff: main::h04b7feb343e229ccgaa (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== 0x16dbca: rt::unwind::try::try_fn::h2403085009213705177 (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== 0x16ff5a: rust_try_inner (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== 0x16ff33: rust_try (in /home/wilfred/projects/bfc/target/debug/bfc) ==10413== address 0x1d684 not stack'd, malloc'd or (recently) free'd
why this? what's correct way handle *char
c api?
according the function's documentation:
use llvmdisposemessage free string.
in general case, if call function in library allocates memory, should call function in library frees memory; should documented part of function's contract.
if documentation function tells use free
, you'll have problem if application not linking free
corresponding library's malloc
(e.g. application links msvcr120, library links msvcr100). reason why libraries provide method deallocate resources allocates you.
the default memory allocator in rust not c's malloc
, allocator called jemalloc. cstring
assumes string allocated rust's memory allocator, when cstring
's destructor runs, runs jemalloc's free
(you can tell je_
-prefixed functions in call stack), fails because string wasn't allocated jemalloc's malloc
.
Comments
Post a Comment