196 {
197 fprintf(
stream,
"memory tracker debug (%zu bytes) at %p ",
size, addr);
198#if defined DC_MSAN_ON
199 fprintf(
stream,
"[MSAN]:");
200
201 for (
size_t i = 0; i <
size; i++) {
202 char const* ptr = (char const*)addr + i;
203 fprintf(
stream,
"\n%p: ", ptr);
204 if (__msan_test_shadow(ptr, 1) != -1) {
205 __msan_unpoison(ptr, 1);
206 fprintf(
stream,
"U [%02x]", *((
unsigned char*)ptr));
207 __msan_poison(ptr, 1);
208 } else {
209 fprintf(
stream,
"I [%02x]", *((
unsigned char*)ptr));
210 }
211 }
212#elif defined DC_ASAN_ON
213
214 const char* addr_start = (const char*)addr;
215 const char* addr_end = addr_start +
size;
216 const char* granule_base =
217 (const char*)((uintptr_t)addr & ~(uintptr_t)0x7U);
218 const char* granule_end = (
const char*)(((uintptr_t)addr +
size + 7U) &
219 ~(uintptr_t)0x7U);
220
221 fprintf(
stream,
"[ASAN]:");
223 "\ndisplaying each 8 byte grandule (asan tracks poisoning as 0-8 bytes from the end)");
226 for (size_t b = 0; b < 8; b++) {
227 fprintf(
stream,
" %lu ", b);
228 }
230 for (const char* p = granule_base; p < granule_end; p += 8) {
231 fprintf(
stream,
"%p: ", p);
232 for (const char* b = p; b < p + 8; b++) {
233 bool const poisoned = __asan_region_is_poisoned((void*)(uintptr_t)b, 1);
234 bool const in_selected = (b >= addr_start && b < addr_end);
235 uint8_t value;
236 if (poisoned) {
237 __asan_unpoison_memory_region((void*)(uintptr_t)b, 1);
238 value = (uint8_t)*b;
239 __asan_poison_memory_region((void*)(uintptr_t)b, 1);
240 } else {
241 value = (uint8_t)*b;
242 }
243
244 char const status = poisoned ? 'P' : 'U';
245
246 if (in_selected) {
247 fprintf(
stream,
"[%c|%02x] ", status, value);
248 } else {
249 fprintf(
stream,
"|%c|%02x| ", status, value);
250 }
251 }
253 }
254#else
255 fprintf(
stream,
"[NO TRACKING]");
256 (void)addr;
258#endif
260}
static DC_PUBLIC FILE * stream(SELF *self)