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 breakpoints on Memento_inited and |
79 | * Memento_Breakpoint. |
80 | * * Run the program. It will stop in Memento_inited. |
81 | * * Execute Memento_setParanoia(1); (In VS use Ctrl-Alt-Q). (Note #1) |
82 | * * Continue execution. |
83 | * * It will detect the memory corruption on the next allocation event |
84 | * after it happens, and stop in Memento_breakpoint. The console should |
85 | * show something like: |
86 | * |
87 | * Freed blocks: |
88 | * 0x172e610(size=288,num=1415) index 256 (0x172e710) onwards corrupted |
89 | * Block last checked OK at allocation 1457. Now 1458. |
90 | * |
91 | * * This means that the block became corrupted between allocation 1457 |
92 | * and 1458 - so if we rerun and stop the program at 1457, we can then |
93 | * step through, possibly with a data breakpoint at 0x172e710 and see |
94 | * when it occurs. |
95 | * * So restart the program from the beginning. When we hit Memento_inited |
96 | * execute Memento_breakAt(1457); (and maybe Memento_setParanoia(1), or |
97 | * Memento_setParanoidAt(1457)) |
98 | * * Continue execution until we hit Memento_breakpoint. |
99 | * * Now you can step through and watch the memory corruption happen. |
100 | * |
101 | * Note #1: Using Memento_setParanoia(1) can cause your program to run |
102 | * very slowly. You may instead choose to use Memento_setParanoia(100) |
103 | * (or some other figure). This will only exhaustively check memory on |
104 | * every 100th allocation event. This trades speed for the size of the |
105 | * average allocation event range in which detection of memory corruption |
106 | * occurs. You may (for example) choose to run once checking every 100 |
107 | * allocations and discover that the corruption happens between events |
108 | * X and X+100. You can then rerun using Memento_paranoidAt(X), and |
109 | * it'll only start exhaustively checking when it reaches X. |
110 | * |
111 | * More than one memory allocator? |
112 | * |
113 | * If you have more than one memory allocator in the system (like for |
114 | * instance the ghostscript chunk allocator, that builds on top of the |
115 | * standard malloc and returns chunks itself), then there are some things |
116 | * to note: |
117 | * |
118 | * * If the secondary allocator gets its underlying blocks from calling |
119 | * malloc, then those will be checked by Memento, but 'subblocks' that |
120 | * are returned to the secondary allocator will not. There is currently |
121 | * no way to fix this other than trying to bypass the secondary |
122 | * allocator. One way I have found to do this with the chunk allocator |
123 | * is to tweak its idea of a 'large block' so that it puts every |
124 | * allocation in its own chunk. Clearly this negates the point of having |
125 | * a secondary allocator, and is therefore not recommended for general |
126 | * use. |
127 | * |
128 | * * Again, if the secondary allocator gets its underlying blocks from |
129 | * calling malloc (and hence Memento) leak detection should still work |
130 | * (but whole blocks will be detected rather than subblocks). |
131 | * |
132 | * * If on every allocation attempt the secondary allocator calls into |
133 | * Memento_failThisEvent(), and fails the allocation if it returns true |
134 | * then more useful features can be used; firstly memory squeezing will |
135 | * work, and secondly, Memento will have a "finer grained" paranoia |
136 | * available to it. |
137 | * |
138 | * Usage with C++: |
139 | * |
140 | * Memento has some experimental code in it to trap new/delete (and |
141 | * new[]/delete[] if required) calls. |
142 | * |
143 | * In order for this to work, either: |
144 | * |
145 | * 1) Build memento.c with the c++ compiler. |
146 | * |
147 | * or |
148 | * |
149 | * 2) Build memento.c as normal with the C compiler, then from any |
150 | * one of your .cpp files, do: |
151 | * |
152 | * #define MEMENTO_CPP_EXTRAS_ONLY |
153 | * #include "memento.c" |
154 | * |
155 | * In the case where MEMENTO is not defined, this will not do anything. |
156 | * |
157 | * Both Windows and GCC provide separate new[] and delete[] operators |
158 | * for arrays. Apparently some systems do not. If this is the case for |
159 | * your system, define MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS. |
160 | */ |
161 | |
162 | #ifndef MEMENTO_H |
163 | |
164 | #include <stdlib.h> |
165 | |
166 | #define MEMENTO_H |
167 | |
168 | #ifndef MEMENTO_UNDERLYING_MALLOC |
169 | #define MEMENTO_UNDERLYING_MALLOC malloc |
170 | #endif |
171 | #ifndef MEMENTO_UNDERLYING_FREE |
172 | #define MEMENTO_UNDERLYING_FREE free |
173 | #endif |
174 | #ifndef MEMENTO_UNDERLYING_REALLOC |
175 | #define MEMENTO_UNDERLYING_REALLOC realloc |
176 | #endif |
177 | #ifndef MEMENTO_UNDERLYING_CALLOC |
178 | #define MEMENTO_UNDERLYING_CALLOC calloc |
179 | #endif |
180 | |
181 | #ifndef MEMENTO_MAXALIGN |
182 | #define MEMENTO_MAXALIGN (sizeof(int)) |
183 | #endif |
184 | |
185 | #define MEMENTO_PREFILL 0xa6 |
186 | #define MEMENTO_POSTFILL 0xa7 |
187 | #define MEMENTO_ALLOCFILL 0xa8 |
188 | #define MEMENTO_FREEFILL 0xa9 |
189 | |
190 | #define MEMENTO_FREELIST_MAX 0x2000000 |
191 | |
192 | int Memento_checkBlock(void *); |
193 | int Memento_checkAllMemory(void); |
194 | int Memento_check(void); |
195 | |
196 | int Memento_setParanoia(int); |
197 | int Memento_paranoidAt(int); |
198 | int Memento_breakAt(int); |
199 | void Memento_breakOnFree(void *a); |
200 | void Memento_breakOnRealloc(void *a); |
201 | int Memento_getBlockNum(void *); |
202 | int Memento_find(void *a); |
203 | void Memento_breakpoint(void); |
204 | int Memento_failAt(int); |
205 | int Memento_failThisEvent(void); |
206 | void Memento_listBlocks(void); |
207 | void Memento_listNewBlocks(void); |
208 | size_t Memento_setMax(size_t); |
209 | void Memento_stats(void); |
210 | void *Memento_label(void *, const char *); |
211 | void Memento_tick(void); |
212 | |
213 | void *Memento_malloc(size_t s); |
214 | void *Memento_realloc(void *, size_t s); |
215 | void Memento_free(void *); |
216 | void *Memento_calloc(size_t, size_t); |
217 | |
218 | void Memento_info(void *addr); |
219 | void Memento_listBlockInfo(void); |
220 | void *Memento_takeByteRef(void *blk); |
221 | void *Memento_dropByteRef(void *blk); |
222 | void *Memento_takeShortRef(void *blk); |
223 | void *Memento_dropShortRef(void *blk); |
224 | void *Memento_takeIntRef(void *blk); |
225 | void *Memento_dropIntRef(void *blk); |
226 | void *Memento_takeRef(void *blk); |
227 | void *Memento_dropRef(void *blk); |
228 | void *Memento_adjustRef(void *blk, int adjust); |
229 | void *Memento_reference(void *blk); |
230 | |
231 | int Memento_checkPointerOrNull(void *blk); |
232 | int Memento_checkBytePointerOrNull(void *blk); |
233 | int Memento_checkShortPointerOrNull(void *blk); |
234 | int Memento_checkIntPointerOrNull(void *blk); |
235 | |
236 | void Memento_startLeaking(void); |
237 | void Memento_stopLeaking(void); |
238 | |
239 | int Memento_sequence(void); |
240 | |
241 | void Memento_fin(void); |
242 | |
243 | void Memento_bt(void); |
244 | |
245 | #ifdef MEMENTO |
246 | |
247 | #ifndef COMPILING_MEMENTO_C |
248 | #define malloc Memento_malloc |
249 | #define free Memento_free |
250 | #define realloc Memento_realloc |
251 | #define calloc Memento_calloc |
252 | #endif |
253 | |
254 | #else |
255 | |
256 | #define Memento_malloc MEMENTO_UNDERLYING_MALLOC |
257 | #define Memento_free MEMENTO_UNDERLYING_FREE |
258 | #define Memento_realloc MEMENTO_UNDERLYING_REALLOC |
259 | #define Memento_calloc MEMENTO_UNDERLYING_CALLOC |
260 | |
261 | #define Memento_checkBlock(A) 0 |
262 | #define Memento_checkAllMemory() 0 |
263 | #define Memento_check() 0 |
264 | #define Memento_setParanoia(A) 0 |
265 | #define Memento_paranoidAt(A) 0 |
266 | #define Memento_breakAt(A) 0 |
267 | #define Memento_breakOnFree(A) 0 |
268 | #define Memento_breakOnRealloc(A) 0 |
269 | #define Memento_getBlockNum(A) 0 |
270 | #define Memento_find(A) 0 |
271 | #define Memento_breakpoint() do {} while (0) |
272 | #define Memento_failAt(A) 0 |
273 | #define Memento_failThisEvent() 0 |
274 | #define Memento_listBlocks() do {} while (0) |
275 | #define Memento_listNewBlocks() do {} while (0) |
276 | #define Memento_setMax(A) 0 |
277 | #define Memento_stats() do {} while (0) |
278 | #define Memento_label(A,B) (A) |
279 | #define Memento_info(A) do {} while (0) |
280 | #define Memento_listBlockInfo() do {} while (0) |
281 | #define Memento_takeByteRef(A) (A) |
282 | #define Memento_dropByteRef(A) (A) |
283 | #define Memento_takeShortRef(A) (A) |
284 | #define Memento_dropShortRef(A) (A) |
285 | #define Memento_takeIntRef(A) (A) |
286 | #define Memento_dropIntRef(A) (A) |
287 | #define Memento_takeRef(A) (A) |
288 | #define Memento_dropRef(A) (A) |
289 | #define Memento_adjustRef(A,V) (A) |
290 | #define Memento_reference(A) (A) |
291 | #define Memento_checkPointerOrNull(A) 0 |
292 | #define Memento_checkBytePointerOrNull(A) 0 |
293 | #define Memento_checkShortPointerOrNull(A) 0 |
294 | #define Memento_checkIntPointerOrNull(A) 0 |
295 | |
296 | #define Memento_tick() do {} while (0) |
297 | #define Memento_startLeaking() do {} while (0) |
298 | #define Memento_stopLeaking() do {} while (0) |
299 | #define Memento_fin() do {} while (0) |
300 | #define Memento_bt() do {} while (0) |
301 | #define Memento_sequence() (0) |
302 | |
303 | #endif /* MEMENTO */ |
304 | |
305 | #endif /* MEMENTO_H */ |
306 | |