15#if defined CUSTOM_MEMORY_TRACKING
18 #if defined __has_feature
19 #if __has_feature(address_sanitizer)
22 #if __has_feature(memory_sanitizer)
30 #if defined __SANITIZE_ADDRESS__
37 #error "cannot support asan and msan simultaneously"
39 #include <sanitizer/asan_interface.h>
41 #include <sanitizer/msan_interface.h>
64#if defined CUSTOM_MEMORY_TRACKING
75 const volatile void* addr,
size_t size) {
82 __msan_poison(addr,
size);
86 __msan_unpoison(addr,
size);
94 __asan_poison_memory_region(addr,
size);
99 __asan_unpoison_memory_region(addr,
size);
113 const void* addr,
size_t size) {
120 if (__msan_test_shadow((
void*)addr,
size) != -1) {
121 PANIC(
"Memory region %p (%zu bytes) is not uninitialised, but should be", addr,
127 if (__msan_test_shadow((
void*)addr,
size) == -1) {
128 PANIC(
"Memory region %p (%zu bytes) is not uninitialised, but should be", addr,
135#elif defined(ASAN_ON)
136 bool const region_is_poisoned = __asan_region_is_poisoned((
void*)addr,
size);
139 if (!region_is_poisoned) {
141 bool const is_next_byte_poisoned =
142 __asan_region_is_poisoned((
void*)((
char*)addr + 1), 1);
152 if (is_at_end_of_granule || is_next_byte_poisoned) {
154 PANIC(
"Memory region %p (%zu bytes) is not poisoned, but should be", addr,
162 if (region_is_poisoned) {
163 PANIC(
"Memory region %p (%zu bytes) is poisoned, but should be accessible", addr,
179 fprintf(
stream,
"memory tracker debug (%zu bytes) at %p ",
size, addr);
181 fprintf(
stream,
"[MSAN]: ")
183 for (
size_t i = 0; i <
size; i++) {
184 fprintf(
stream,
"\n%p: ", (
char*)addr + i);
185 if (__msan_test_shadow((
char*)addr + i, 1) == -1) {
186 fprintf(
stream,
"U [%02x]", *((
unsigned char*)addr + i));
188 fprintf(
stream,
"I [%02x]", *((
unsigned char*)addr + i));
191#elif defined(ASAN_ON)
193 char* addr_start = (
char*)addr;
194 char* addr_end = addr_start +
size;
195 char* granule_base = (
char*)((uintptr_t)addr & ~0x7);
197 (
char*)(((uintptr_t)addr +
size + 7) & ~0x7);
199 fprintf(
stream,
"[ASAN]:");
201 "\ndisplaying each 8 byte grandule (asan tracks poisoning as 0-8 bytes from the end)");
204 for (
size_t b = 0; b < 8; b++) {
205 fprintf(
stream,
" %lu ", b);
208 for (
char* p = granule_base; p < granule_end; p += 8) {
209 fprintf(
stream,
"%p: ", p);
210 for (
char* b = p; b < p + 8; b++) {
211 bool const poisoned = __asan_region_is_poisoned(b, 1);
212 bool const in_selected = (b >= addr_start && b < addr_end);
215 __asan_unpoison_memory_region(b, 1);
217 __asan_poison_memory_region(b, 1);
222 char const status = poisoned ?
'P' :
'U';
225 fprintf(
stream,
"[%c|%02x] ", status, value);
227 fprintf(
stream,
"|%c|%02x| ", status, value);
233 fprintf(
stream,
"[NO TRACKING]");
static INDEX_TYPE size(SELF const *self)
static bool INLINE CONST is_aligned_pow2_exp(const void *ptr, unsigned exp)
static const memory_tracker_level memory_tracker_global_level
static void memory_tracker_check(memory_tracker_level level, memory_tracker_capability cap, const void *addr, size_t size)
@ MEMORY_TRACKER_LVL_NONE
@ MEMORY_TRACKER_LVL_CONTAINER
@ MEMORY_TRACKER_LVL_ALLOC
static void memory_tracker_set(memory_tracker_level level, memory_tracker_capability cap, const volatile void *addr, size_t size)
memory_tracker_capability
a wrapper over asan & msan Containers and allocators can use this for custom asan & msan poisoning,...
@ MEMORY_TRACKER_CAP_NONE
@ MEMORY_TRACKER_CAP_WRITE
@ MEMORY_TRACKER_CAP_READ_WRITE
static void memory_tracker_debug(FILE *stream, const void *addr, size_t size)
static FILE * stream(SELF *self)
Opens a file for.