Simple wrapper for malloc call in Rust

Code

extern crate libc;

use libc::{c_void, size_t};
use std::cell::RefCell;


thread_local! {
    pub(crate) static NESTED: RefCell<bool> = RefCell::new(false);
}

extern "C" {
    #[link_name = "__libc_malloc"]
    fn libc_malloc_real(size: size_t) -> *mut c_void;
}

#[no_mangle]
pub extern "C" fn malloc(size: size_t) -> *mut c_void {
    let res = NESTED.try_with(|nested| {
        if *nested.borrow() {
            unsafe {
                libc_malloc_real(size)
            }
        } else {
            *nested.borrow_mut() = true;
            println!("<our> malloc call ({})", size);
            let res = unsafe {libc_malloc_real(size)};
            *nested.borrow_mut() = false;
            res
        }
    });

    match res {
        Ok(res) => res,
        // alloc called during thread destruction.
        Err(..) => unsafe {libc_malloc_real(size)},
    }
}

This example is grabbed from malloq_freq library

GCC example:

For GCC you can use --wrap=malloc argument and in code you can have this:

    void *__real_malloc(size_t);
    void *__wrap_malloc(size_t size) {
        ...
        return __real_malloc(size);
    }

source

On MacOS DYLD_INSERT_LIBRARIES is used instead of LD_PRELOAD

Created:

Last updated:

Category: snippet

Tags: snippet rust memory malloc