1 /* Copyright (C) 2009-2018 Artifex Software, Inc. 2 All Rights Reserved. 3 4 This software is provided AS-IS with no warranty, either express or 5 implied. 6 7 This software is distributed under license and may not be copied, modified 8 or distributed except as expressly authorized under the terms of that 9 license. Refer to licensing information at http://www.artifex.com 10 or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, 11 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. 12 */ 13 14 /* Memento: A library to aid debugging of memory leaks/heap corruption. 15 * 16 * Usage (with C): 17 * First, build your project with MEMENTO defined, and include this 18 * header file wherever you use malloc, realloc or free. 19 * This header file will use macros to point malloc, realloc and free to 20 * point to Memento_malloc, Memento_realloc, Memento_free. 21 * 22 * Run your program, and all mallocs/frees/reallocs should be redirected 23 * through here. When the program exits, you will get a list of all the 24 * leaked blocks, together with some helpful statistics. You can get the 25 * same list of allocated blocks at any point during program execution by 26 * calling Memento_listBlocks(); 27 * 28 * Every call to malloc/free/realloc counts as an 'allocation event'. 29 * On each event Memento increments a counter. Every block is tagged with 30 * the current counter on allocation. Every so often during program 31 * execution, the heap is checked for consistency. By default this happens 32 * after 1024 events, then after 2048 events, then after 4096 events, etc. 33 * This can be changed at runtime by using Memento_setParanoia(int level). 34 * 0 turns off such checking, 1 sets checking to happen on every event, 35 * any positive number n sets checking to happen once every n events, 36 * and any negative number n sets checking to happen after -n events, then 37 * after -2n events etc. 38 * 39 * The default paranoia level is therefore -1024. 40 * 41 * Memento keeps blocks around for a while after they have been freed, and 42 * checks them as part of these heap checks to see if they have been 43 * written to (or are freed twice etc). 44 * 45 * A given heap block can be checked for consistency (it's 'pre' and 46 * 'post' guard blocks are checked to see if they have been written to) 47 * by calling Memento_checkBlock(void *blockAddress); 48 * 49 * A check of all the memory can be triggered by calling Memento_check(); 50 * (or Memento_checkAllMemory(); if you'd like it to be quieter). 51 * 52 * A good place to breakpoint is Memento_breakpoint, as this will then 53 * trigger your debugger if an error is detected. This is done 54 * automatically for debug windows builds. 55 * 56 * If a block is found to be corrupt, information will be printed to the 57 * console, including the address of the block, the size of the block, 58 * the type of corruption, the number of the block and the event on which 59 * it last passed a check for correctness. 60 * 61 * If you rerun, and call Memento_paranoidAt(int event); with this number 62 * the code will wait until it reaches that event and then start 63 * checking the heap after every allocation event. Assuming it is a 64 * deterministic failure, you should then find out where in your program 65 * the error is occurring (between event x-1 and event x). 66 * 67 * Then you can rerun the program again, and call 68 * Memento_breakAt(int event); and the program will call 69 * Memento_Breakpoint() when event x is reached, enabling you to step 70 * through. 71 * 72 * Memento_find(address) will tell you what block (if any) the given 73 * address is in. 74 * 75 * An example: 76 * Suppose we have a gs invocation that crashes with memory corruption. 77 * * Build with -DMEMENTO. 78 * * In your debugger put a breakpoint on Memento_breakpoint. 79 * * Run the program. It will stop in Memento_inited. 80 * * Execute Memento_setParanoia(1); (In VS use Ctrl-Alt-Q). (Note #1) 81 * * Continue execution. 82 * * It will detect the memory corruption on the next allocation event 83 * after it happens, and stop in Memento_breakpoint. The console should 84 * show something like: 85 * 86 * Freed blocks: 87 * 0x172e610(size=288,num=1415) index 256 (0x172e710) onwards corrupted 88 * Block last checked OK at allocation 1457. Now 1458. 89 * 90 * * This means that the block became corrupted between allocation 1457 91 * and 1458 - so if we rerun and stop the program at 1457, we can then 92 * step through, possibly with a data breakpoint at 0x172e710 and see 93 * when it occurs. 94 * * So restart the program from the beginning. When we stop after 95 * initialisation execute Memento_breakAt(1457); (and maybe 96 * Memento_setParanoia(1), or Memento_setParanoidAt(1457)) 97 * * Continue execution until we hit Memento_breakpoint. 98 * * Now you can step through and watch the memory corruption happen. 99 * 100 * Note #1: Using Memento_setParanoia(1) can cause your program to run 101 * very slowly. You may instead choose to use Memento_setParanoia(100) 102 * (or some other figure). This will only exhaustively check memory on 103 * every 100th allocation event. This trades speed for the size of the 104 * average allocation event range in which detection of memory corruption 105 * occurs. You may (for example) choose to run once checking every 100 106 * allocations and discover that the corruption happens between events 107 * X and X+100. You can then rerun using Memento_paranoidAt(X), and 108 * it'll only start exhaustively checking when it reaches X. 109 * 110 * More than one memory allocator? 111 * 112 * If you have more than one memory allocator in the system (like for 113 * instance the ghostscript chunk allocator, that builds on top of the 114 * standard malloc and returns chunks itself), then there are some things 115 * to note: 116 * 117 * * If the secondary allocator gets its underlying blocks from calling 118 * malloc, then those will be checked by Memento, but 'subblocks' that 119 * are returned to the secondary allocator will not. There is currently 120 * no way to fix this other than trying to bypass the secondary 121 * allocator. One way I have found to do this with the chunk allocator 122 * is to tweak its idea of a 'large block' so that it puts every 123 * allocation in its own chunk. Clearly this negates the point of having 124 * a secondary allocator, and is therefore not recommended for general 125 * use. 126 * 127 * * Again, if the secondary allocator gets its underlying blocks from 128 * calling malloc (and hence Memento) leak detection should still work 129 * (but whole blocks will be detected rather than subblocks). 130 * 131 * * If on every allocation attempt the secondary allocator calls into 132 * Memento_failThisEvent(), and fails the allocation if it returns true 133 * then more useful features can be used; firstly memory squeezing will 134 * work, and secondly, Memento will have a "finer grained" paranoia 135 * available to it. 136 * 137 * Usage with C++: 138 * 139 * Memento has some experimental code in it to trap new/delete (and 140 * new[]/delete[] if required) calls. 141 * 142 * In order for this to work, either: 143 * 144 * 1) Build memento.c with the c++ compiler. 145 * 146 * or 147 * 148 * 2) Build memento.c as normal with the C compiler, then from any 149 * one of your .cpp files, do: 150 * 151 * #define MEMENTO_CPP_EXTRAS_ONLY 152 * #include "memento.c" 153 * 154 * In the case where MEMENTO is not defined, this will not do anything. 155 * 156 * Both Windows and GCC provide separate new[] and delete[] operators 157 * for arrays. Apparently some systems do not. If this is the case for 158 * your system, define MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS. 159 * 160 * "libbacktrace.so failed to load" 161 * 162 * In order to give nice backtraces on unix, Memento will try to use 163 * a libbacktrace dynamic library. If it can't find it, you'll see 164 * that warning, and your backtraces won't include file/line information. 165 * 166 * To fix this you'll need to build your own libbacktrace. Don't worry 167 * it's really easy: 168 * git clone git://github.com/ianlancetaylor/libbacktrace 169 * cd libbacktrace 170 * ./configure 171 * make 172 * 173 * This leaves the build .so as .libs/libbacktrace.so 174 * 175 * Memento will look for this on LD_LIBRARY_PATH, or in /opt/lib/, 176 * or in /lib/, or in /usr/lib/, or in /usr/local/lib/. I recommend 177 * using /opt/lib/ as this won't conflict with anything that you 178 * get via a package manager like apt. 179 * 180 * sudo mkdir /opt 181 * sudo mkdir /opt/lib 182 * sudo cp .libs/libbacktrace.so /opt/lib/ 183 */ 184 185 #ifndef MEMENTO_H 186 187 #include <stdlib.h> 188 189 #define MEMENTO_H 190 191 #ifndef MEMENTO_UNDERLYING_MALLOC 192 #define MEMENTO_UNDERLYING_MALLOC malloc 193 #endif 194 #ifndef MEMENTO_UNDERLYING_FREE 195 #define MEMENTO_UNDERLYING_FREE free 196 #endif 197 #ifndef MEMENTO_UNDERLYING_REALLOC 198 #define MEMENTO_UNDERLYING_REALLOC realloc 199 #endif 200 #ifndef MEMENTO_UNDERLYING_CALLOC 201 #define MEMENTO_UNDERLYING_CALLOC calloc 202 #endif 203 204 #ifndef MEMENTO_MAXALIGN 205 #define MEMENTO_MAXALIGN (sizeof(int)) 206 #endif 207 208 #define MEMENTO_PREFILL 0xa6 209 #define MEMENTO_POSTFILL 0xa7 210 #define MEMENTO_ALLOCFILL 0xa8 211 #define MEMENTO_FREEFILL 0xa9 212 213 #define MEMENTO_FREELIST_MAX 0x2000000 214 215 int Memento_checkBlock(void *); 216 int Memento_checkAllMemory(void); 217 int Memento_check(void); 218 219 int Memento_setParanoia(int); 220 int Memento_paranoidAt(int); 221 int Memento_breakAt(int); 222 void Memento_breakOnFree(void *a); 223 void Memento_breakOnRealloc(void *a); 224 int Memento_getBlockNum(void *); 225 int Memento_find(void *a); 226 void Memento_breakpoint(void); 227 int Memento_failAt(int); 228 int Memento_failThisEvent(void); 229 void Memento_listBlocks(void); 230 void Memento_listNewBlocks(void); 231 size_t Memento_setMax(size_t); 232 void Memento_stats(void); 233 void *Memento_label(void *, const char *); 234 void Memento_tick(void); 235 236 void *Memento_malloc(size_t s); 237 void *Memento_realloc(void *, size_t s); 238 void Memento_free(void *); 239 void *Memento_calloc(size_t, size_t); 240 241 void Memento_info(void *addr); 242 void Memento_listBlockInfo(void); 243 void *Memento_takeByteRef(void *blk); 244 void *Memento_dropByteRef(void *blk); 245 void *Memento_takeShortRef(void *blk); 246 void *Memento_dropShortRef(void *blk); 247 void *Memento_takeIntRef(void *blk); 248 void *Memento_dropIntRef(void *blk); 249 void *Memento_takeRef(void *blk); 250 void *Memento_dropRef(void *blk); 251 void *Memento_adjustRef(void *blk, int adjust); 252 void *Memento_reference(void *blk); 253 254 int Memento_checkPointerOrNull(void *blk); 255 int Memento_checkBytePointerOrNull(void *blk); 256 int Memento_checkShortPointerOrNull(void *blk); 257 int Memento_checkIntPointerOrNull(void *blk); 258 259 void Memento_startLeaking(void); 260 void Memento_stopLeaking(void); 261 262 int Memento_sequence(void); 263 264 int Memento_squeezing(void); 265 266 void Memento_fin(void); 267 268 void Memento_bt(void); 269 270 #ifdef MEMENTO 271 272 #ifndef COMPILING_MEMENTO_C 273 #define malloc Memento_malloc 274 #define free Memento_free 275 #define realloc Memento_realloc 276 #define calloc Memento_calloc 277 #endif 278 279 #else 280 281 #define Memento_malloc MEMENTO_UNDERLYING_MALLOC 282 #define Memento_free MEMENTO_UNDERLYING_FREE 283 #define Memento_realloc MEMENTO_UNDERLYING_REALLOC 284 #define Memento_calloc MEMENTO_UNDERLYING_CALLOC 285 286 #define Memento_checkBlock(A) 0 287 #define Memento_checkAllMemory() 0 288 #define Memento_check() 0 289 #define Memento_setParanoia(A) 0 290 #define Memento_paranoidAt(A) 0 291 #define Memento_breakAt(A) 0 292 #define Memento_breakOnFree(A) 0 293 #define Memento_breakOnRealloc(A) 0 294 #define Memento_getBlockNum(A) 0 295 #define Memento_find(A) 0 296 #define Memento_breakpoint() do {} while (0) 297 #define Memento_failAt(A) 0 298 #define Memento_failThisEvent() 0 299 #define Memento_listBlocks() do {} while (0) 300 #define Memento_listNewBlocks() do {} while (0) 301 #define Memento_setMax(A) 0 302 #define Memento_stats() do {} while (0) 303 #define Memento_label(A,B) (A) 304 #define Memento_info(A) do {} while (0) 305 #define Memento_listBlockInfo() do {} while (0) 306 #define Memento_takeByteRef(A) (A) 307 #define Memento_dropByteRef(A) (A) 308 #define Memento_takeShortRef(A) (A) 309 #define Memento_dropShortRef(A) (A) 310 #define Memento_takeIntRef(A) (A) 311 #define Memento_dropIntRef(A) (A) 312 #define Memento_takeRef(A) (A) 313 #define Memento_dropRef(A) (A) 314 #define Memento_adjustRef(A,V) (A) 315 #define Memento_reference(A) (A) 316 #define Memento_checkPointerOrNull(A) 0 317 #define Memento_checkBytePointerOrNull(A) 0 318 #define Memento_checkShortPointerOrNull(A) 0 319 #define Memento_checkIntPointerOrNull(A) 0 320 321 #define Memento_tick() do {} while (0) 322 #define Memento_startLeaking() do {} while (0) 323 #define Memento_stopLeaking() do {} while (0) 324 #define Memento_fin() do {} while (0) 325 #define Memento_bt() do {} while (0) 326 #define Memento_sequence() (0) 327 #define Memento_squeezing() (0) 328 329 #endif /* MEMENTO */ 330 331 #endif /* MEMENTO_H */ 332