/ source / mimalloc / include / mimalloc / track.h
track.h
  1  /* ----------------------------------------------------------------------------
  2  Copyright (c) 2018-2023, Microsoft Research, Daan Leijen
  3  This is free software; you can redistribute it and/or modify it under the
  4  terms of the MIT license. A copy of the license can be found in the file
  5  "LICENSE" at the root of this distribution.
  6  -----------------------------------------------------------------------------*/
  7  #pragma once
  8  #ifndef MIMALLOC_TRACK_H
  9  #define MIMALLOC_TRACK_H
 10  
 11  /* ------------------------------------------------------------------------------------------------------
 12  Track memory ranges with macros for tools like Valgrind address sanitizer, or other memory checkers.
 13  These can be defined for tracking allocation:
 14  
 15    #define mi_track_malloc_size(p,reqsize,size,zero)
 16    #define mi_track_free_size(p,_size)
 17  
 18  The macros are set up such that the size passed to `mi_track_free_size`
 19  always matches the size of `mi_track_malloc_size`. (currently, `size == mi_usable_size(p)`).
 20  The `reqsize` is what the user requested, and `size >= reqsize`.
 21  The `size` is either byte precise (and `size==reqsize`) if `MI_PADDING` is enabled,
 22  or otherwise it is the usable block size which may be larger than the original request.
 23  Use `_mi_block_size_of(void* p)` to get the full block size that was allocated (including padding etc).
 24  The `zero` parameter is `true` if the allocated block is zero initialized.
 25  
 26  Optional:
 27  
 28    #define mi_track_align(p,alignedp,offset,size)
 29    #define mi_track_resize(p,oldsize,newsize)
 30    #define mi_track_init()
 31  
 32  The `mi_track_align` is called right after a `mi_track_malloc` for aligned pointers in a block.
 33  The corresponding `mi_track_free` still uses the block start pointer and original size (corresponding to the `mi_track_malloc`).
 34  The `mi_track_resize` is currently unused but could be called on reallocations within a block.
 35  `mi_track_init` is called at program start.
 36  
 37  The following macros are for tools like asan and valgrind to track whether memory is
 38  defined, undefined, or not accessible at all:
 39  
 40    #define mi_track_mem_defined(p,size)
 41    #define mi_track_mem_undefined(p,size)
 42    #define mi_track_mem_noaccess(p,size)
 43  
 44  -------------------------------------------------------------------------------------------------------*/
 45  
 46  #if MI_TRACK_VALGRIND
 47  // valgrind tool
 48  
 49  #define MI_TRACK_ENABLED      1
 50  #define MI_TRACK_HEAP_DESTROY 1           // track free of individual blocks on heap_destroy
 51  #define MI_TRACK_TOOL         "valgrind"
 52  
 53  #include <valgrind/valgrind.h>
 54  #include <valgrind/memcheck.h>
 55  
 56  #define mi_track_malloc_size(p,reqsize,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero)
 57  #define mi_track_free_size(p,_size)               VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/)
 58  #define mi_track_resize(p,oldsize,newsize)        VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/)
 59  #define mi_track_mem_defined(p,size)              VALGRIND_MAKE_MEM_DEFINED(p,size)
 60  #define mi_track_mem_undefined(p,size)            VALGRIND_MAKE_MEM_UNDEFINED(p,size)
 61  #define mi_track_mem_noaccess(p,size)             VALGRIND_MAKE_MEM_NOACCESS(p,size)
 62  
 63  #elif MI_TRACK_ASAN
 64  // address sanitizer
 65  
 66  #define MI_TRACK_ENABLED      1
 67  #define MI_TRACK_HEAP_DESTROY 0
 68  #define MI_TRACK_TOOL         "asan"
 69  
 70  #include <sanitizer/asan_interface.h>
 71  
 72  #define mi_track_malloc_size(p,reqsize,size,zero) ASAN_UNPOISON_MEMORY_REGION(p,size)
 73  #define mi_track_free_size(p,size)                ASAN_POISON_MEMORY_REGION(p,size)
 74  #define mi_track_mem_defined(p,size)              ASAN_UNPOISON_MEMORY_REGION(p,size)
 75  #define mi_track_mem_undefined(p,size)            ASAN_UNPOISON_MEMORY_REGION(p,size)
 76  #define mi_track_mem_noaccess(p,size)             ASAN_POISON_MEMORY_REGION(p,size)
 77  
 78  #elif MI_TRACK_ETW
 79  // windows event tracing
 80  
 81  #define MI_TRACK_ENABLED      1
 82  #define MI_TRACK_HEAP_DESTROY 1
 83  #define MI_TRACK_TOOL         "ETW"
 84  
 85  #include "../src/prim/windows/etw.h"
 86  
 87  #define mi_track_init()                           EventRegistermicrosoft_windows_mimalloc();
 88  #define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size)
 89  #define mi_track_free_size(p,size)                EventWriteETW_MI_FREE((UINT64)(p), size)
 90  
 91  #else
 92  // no tracking
 93  
 94  #define MI_TRACK_ENABLED      0
 95  #define MI_TRACK_HEAP_DESTROY 0
 96  #define MI_TRACK_TOOL         "none"
 97  
 98  #define mi_track_malloc_size(p,reqsize,size,zero)
 99  #define mi_track_free_size(p,_size)
100  
101  #endif
102  
103  // -------------------
104  // Utility definitions
105  
106  #ifndef mi_track_resize
107  #define mi_track_resize(p,oldsize,newsize)      mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false)
108  #endif
109  
110  #ifndef mi_track_align
111  #define mi_track_align(p,alignedp,offset,size)  mi_track_mem_noaccess(p,offset)
112  #endif
113  
114  #ifndef mi_track_init
115  #define mi_track_init()
116  #endif
117  
118  #ifndef mi_track_mem_defined
119  #define mi_track_mem_defined(p,size)
120  #endif
121  
122  #ifndef mi_track_mem_undefined
123  #define mi_track_mem_undefined(p,size)
124  #endif
125  
126  #ifndef mi_track_mem_noaccess
127  #define mi_track_mem_noaccess(p,size)
128  #endif
129  
130  
131  #if MI_PADDING
132  #define mi_track_malloc(p,reqsize,zero) \
133    if ((p)!=NULL) { \
134      mi_assert_internal(mi_usable_size(p)==(reqsize)); \
135      mi_track_malloc_size(p,reqsize,reqsize,zero); \
136    }
137  #else
138  #define mi_track_malloc(p,reqsize,zero) \
139    if ((p)!=NULL) { \
140      mi_assert_internal(mi_usable_size(p)>=(reqsize)); \
141      mi_track_malloc_size(p,reqsize,mi_usable_size(p),zero); \
142    }
143  #endif
144  
145  #endif