use std::ffi::CStr;
use super::{
bindings, fatal_error, valgrind_do_client_request_expr, valgrind_do_client_request_stmt,
};
pub type BlockHandle = usize;
#[derive(Debug, Default, PartialEq, Eq, Clone, Hash)]
pub struct LeakCounts {
pub dubious: cty::c_ulong,
pub leaked: cty::c_ulong,
pub reachable: cty::c_ulong,
pub suppressed: cty::c_ulong,
}
#[inline(always)]
pub fn make_mem_noaccess(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::make_mem_noaccess",
0,
bindings::GR_MemcheckClientRequest::GR_MAKE_MEM_NOACCESS,
addr as usize,
len,
0,
0,
0
)
}
#[inline(always)]
pub fn make_mem_undefined(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::make_mem_undefined",
0,
bindings::GR_MemcheckClientRequest::GR_MAKE_MEM_UNDEFINED,
addr as usize,
len,
0,
0,
0
)
}
#[inline(always)]
pub fn make_mem_defined(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::make_mem_defined",
0,
bindings::GR_MemcheckClientRequest::GR_MAKE_MEM_DEFINED,
addr as usize,
len,
0,
0,
0
)
}
#[inline(always)]
pub fn make_mem_defined_if_addressable(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::make_mem_defined_if_addressable",
0,
bindings::GR_MemcheckClientRequest::GR_MAKE_MEM_DEFINED_IF_ADDRESSABLE,
addr as usize,
len,
0,
0,
0
)
}
#[inline(always)]
pub fn create_block<T>(addr: *const (), len: usize, desc: T) -> BlockHandle
where
T: AsRef<CStr>,
{
do_client_request!(
"memcheck::create_block",
0,
bindings::GR_MemcheckClientRequest::GR_CREATE_BLOCK,
addr as usize,
len,
desc.as_ref().as_ptr() as usize,
0,
0
)
}
#[inline(always)]
pub fn discard<T>(handle: BlockHandle) -> usize {
do_client_request!(
"memcheck::discard",
0,
bindings::GR_MemcheckClientRequest::GR_DISCARD,
0,
handle,
0,
0,
0
)
}
#[inline(always)]
pub fn check_mem_is_addressable(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::check_mem_is_addressable",
0,
bindings::GR_MemcheckClientRequest::GR_CHECK_MEM_IS_ADDRESSABLE,
addr as usize,
len,
0,
0,
0
)
}
#[inline(always)]
pub fn check_mem_is_defined(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::check_mem_is_defined",
0,
bindings::GR_MemcheckClientRequest::GR_CHECK_MEM_IS_DEFINED,
addr as usize,
len,
0,
0,
0
)
}
#[inline(always)]
pub fn check_value_is_defined<T>(value: &T) -> usize {
do_client_request!(
"memcheck::check_value_is_defined",
0,
bindings::GR_MemcheckClientRequest::GR_CHECK_MEM_IS_DEFINED,
value as *const T as usize,
core::mem::size_of::<T>(),
0,
0,
0
)
}
#[inline(always)]
pub fn do_leak_check() {
do_client_request!(
"memcheck::do_leak_check",
bindings::GR_MemcheckClientRequest::GR_DO_LEAK_CHECK,
0,
0,
0,
0,
0
);
}
#[inline(always)]
pub fn do_added_leak_check() {
do_client_request!(
"memcheck::do_added_leak_check",
bindings::GR_MemcheckClientRequest::GR_DO_LEAK_CHECK,
0,
1,
0,
0,
0
);
}
#[inline(always)]
pub fn do_changed_leak_check() {
do_client_request!(
"memcheck::do_changed_leak_check",
bindings::GR_MemcheckClientRequest::GR_DO_LEAK_CHECK,
0,
2,
0,
0,
0
);
}
#[inline(always)]
pub fn do_new_leak_check() {
do_client_request!(
"memcheck::do_new_leak_check",
bindings::GR_MemcheckClientRequest::GR_DO_LEAK_CHECK,
0,
3,
0,
0,
0
);
}
#[inline(always)]
pub fn do_quick_leak_check() {
do_client_request!(
"memcheck::do_quick_leak_check",
bindings::GR_MemcheckClientRequest::GR_DO_LEAK_CHECK,
1,
0,
0,
0,
0
);
}
#[inline(always)]
pub fn count_leaks() -> LeakCounts {
let leaks = LeakCounts::default();
do_client_request!(
"memcheck::count_leaks",
bindings::GR_MemcheckClientRequest::GR_COUNT_LEAKS,
std::ptr::addr_of!(leaks.leaked) as usize,
std::ptr::addr_of!(leaks.dubious) as usize,
std::ptr::addr_of!(leaks.reachable) as usize,
std::ptr::addr_of!(leaks.suppressed) as usize,
0
);
leaks
}
#[inline(always)]
pub fn count_leak_blocks() -> LeakCounts {
let leaks = LeakCounts::default();
do_client_request!(
"memcheck::count_leak_blocks",
bindings::GR_MemcheckClientRequest::GR_COUNT_LEAK_BLOCKS,
std::ptr::addr_of!(leaks.leaked) as usize,
std::ptr::addr_of!(leaks.dubious) as usize,
std::ptr::addr_of!(leaks.reachable) as usize,
std::ptr::addr_of!(leaks.suppressed) as usize,
0
);
leaks
}
#[inline(always)]
pub fn get_vbits(addr: *const (), bits: &mut [u8], len: usize) -> usize {
do_client_request!(
"memcheck::get_vbits",
0,
bindings::GR_MemcheckClientRequest::GR_GET_VBITS,
addr as usize,
bits.as_ptr() as usize,
len,
0,
0
)
}
#[inline(always)]
pub fn set_vbits(addr: *const (), bits: &[u8], len: usize) -> usize {
do_client_request!(
"memcheck::set_vbits",
0,
bindings::GR_MemcheckClientRequest::GR_SET_VBITS,
addr as usize,
bits.as_ptr() as usize,
len,
0,
0
)
}
#[inline(always)]
pub fn disable_addr_error_reporting_in_range(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::disable_addr_error_reporting_in_range",
0,
bindings::GR_MemcheckClientRequest::GR_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE,
addr as usize,
len,
0,
0,
0
)
}
#[inline(always)]
pub fn enable_addr_error_reporting_in_range(addr: *const (), len: usize) -> usize {
do_client_request!(
"memcheck::enable_addr_error_reporting_in_range",
0,
bindings::GR_MemcheckClientRequest::GR_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE,
addr as usize,
len,
0,
0,
0
)
}