comparison mupdf-source/include/mupdf/memento.h @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /* Copyright (C) 2009-2022 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,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file COPYING in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
13 CA 94129, USA, for further information.
14 */
15
16 /* Memento: A library to aid debugging of memory leaks/heap corruption.
17 *
18 * Usage (with C):
19 * First, build your project with MEMENTO defined, and include this
20 * header file wherever you use malloc, realloc or free.
21 * This header file will use macros to point malloc, realloc and free to
22 * point to Memento_malloc, Memento_realloc, Memento_free.
23 *
24 * Run your program, and all mallocs/frees/reallocs should be redirected
25 * through here. When the program exits, you will get a list of all the
26 * leaked blocks, together with some helpful statistics. You can get the
27 * same list of allocated blocks at any point during program execution by
28 * calling Memento_listBlocks();
29 *
30 * Every call to malloc/free/realloc counts as an 'allocation event'.
31 * On each event Memento increments a counter. Every block is tagged with
32 * the current counter on allocation. Every so often during program
33 * execution, the heap is checked for consistency. By default this happens
34 * after 1024 events, then after 2048 events, then after 4096 events, etc.
35 * This can be changed at runtime by using Memento_setParanoia(int level).
36 * 0 turns off such checking, 1 sets checking to happen on every event,
37 * any positive number n sets checking to happen once every n events,
38 * and any negative number n sets checking to happen after -n events, then
39 * after -2n events etc.
40 *
41 * The default paranoia level is therefore -1024.
42 *
43 * Memento keeps blocks around for a while after they have been freed, and
44 * checks them as part of these heap checks to see if they have been
45 * written to (or are freed twice etc).
46 *
47 * A given heap block can be checked for consistency (it's 'pre' and
48 * 'post' guard blocks are checked to see if they have been written to)
49 * by calling Memento_checkBlock(void *blockAddress);
50 *
51 * A check of all the memory can be triggered by calling Memento_check();
52 * (or Memento_checkAllMemory(); if you'd like it to be quieter).
53 *
54 * A good place to breakpoint is Memento_breakpoint, as this will then
55 * trigger your debugger if an error is detected. This is done
56 * automatically for debug windows builds.
57 *
58 * If a block is found to be corrupt, information will be printed to the
59 * console, including the address of the block, the size of the block,
60 * the type of corruption, the number of the block and the event on which
61 * it last passed a check for correctness.
62 *
63 * If you rerun, and call Memento_paranoidAt(int event); with this number
64 * the code will wait until it reaches that event and then start
65 * checking the heap after every allocation event. Assuming it is a
66 * deterministic failure, you should then find out where in your program
67 * the error is occurring (between event x-1 and event x).
68 *
69 * Then you can rerun the program again, and call
70 * Memento_breakAt(int event); and the program will call
71 * Memento_Breakpoint() when event x is reached, enabling you to step
72 * through.
73 *
74 * Memento_find(address) will tell you what block (if any) the given
75 * address is in.
76 *
77 * An example:
78 * Suppose we have a gs invocation that crashes with memory corruption.
79 * * Build with -DMEMENTO.
80 * * In your debugger put a breakpoint on Memento_breakpoint.
81 * * Run the program. It will stop in Memento_inited.
82 * * Execute Memento_setParanoia(1); (In VS use Ctrl-Alt-Q). (Note #1)
83 * * Continue execution.
84 * * It will detect the memory corruption on the next allocation event
85 * after it happens, and stop in Memento_breakpoint. The console should
86 * show something like:
87 *
88 * Freed blocks:
89 * 0x172e610(size=288,num=1415) index 256 (0x172e710) onwards corrupted
90 * Block last checked OK at allocation 1457. Now 1458.
91 *
92 * * This means that the block became corrupted between allocation 1457
93 * and 1458 - so if we rerun and stop the program at 1457, we can then
94 * step through, possibly with a data breakpoint at 0x172e710 and see
95 * when it occurs.
96 * * So restart the program from the beginning. When we stop after
97 * initialisation execute Memento_breakAt(1457); (and maybe
98 * Memento_setParanoia(1), or Memento_setParanoidAt(1457))
99 * * Continue execution until we hit Memento_breakpoint.
100 * * Now you can step through and watch the memory corruption happen.
101 *
102 * Note #1: Using Memento_setParanoia(1) can cause your program to run
103 * very slowly. You may instead choose to use Memento_setParanoia(100)
104 * (or some other figure). This will only exhaustively check memory on
105 * every 100th allocation event. This trades speed for the size of the
106 * average allocation event range in which detection of memory corruption
107 * occurs. You may (for example) choose to run once checking every 100
108 * allocations and discover that the corruption happens between events
109 * X and X+100. You can then rerun using Memento_paranoidAt(X), and
110 * it'll only start exhaustively checking when it reaches X.
111 *
112 * More than one memory allocator?
113 *
114 * If you have more than one memory allocator in the system (like for
115 * instance the ghostscript chunk allocator, that builds on top of the
116 * standard malloc and returns chunks itself), then there are some things
117 * to note:
118 *
119 * * If the secondary allocator gets its underlying blocks from calling
120 * malloc, then those will be checked by Memento, but 'subblocks' that
121 * are returned to the secondary allocator will not. There is currently
122 * no way to fix this other than trying to bypass the secondary
123 * allocator. One way I have found to do this with the chunk allocator
124 * is to tweak its idea of a 'large block' so that it puts every
125 * allocation in its own chunk. Clearly this negates the point of having
126 * a secondary allocator, and is therefore not recommended for general
127 * use.
128 *
129 * * Again, if the secondary allocator gets its underlying blocks from
130 * calling malloc (and hence Memento) leak detection should still work
131 * (but whole blocks will be detected rather than subblocks).
132 *
133 * * If on every allocation attempt the secondary allocator calls into
134 * Memento_failThisEvent(), and fails the allocation if it returns true
135 * then more useful features can be used; firstly memory squeezing will
136 * work, and secondly, Memento will have a "finer grained" paranoia
137 * available to it.
138 *
139 * Usage with C++:
140 *
141 * Memento has some experimental code in it to trap new/delete (and
142 * new[]/delete[] if required) calls.
143 *
144 * In all cases, Memento will provide a C API that new/delete
145 * operators can be built upon:
146 * void *Memento_cpp_new(size_t size);
147 * void Memento_cpp_delete(void *pointer);
148 * void *Memento_cpp_new_array(size_t size);
149 * void Memento_cpp_delete_array(void *pointer);
150 *
151 * There are various ways that actual operator definitions can be
152 * provided:
153 *
154 * 1) If memento.c is built with the c++ compiler, then global new
155 * and delete operators will be built in to memento by default.
156 *
157 * 2) If memento.c is built as normal with the C compiler, then
158 * no such veneers will be built in. The caller must provide them
159 * themselves. This can be done either by:
160 *
161 * a) Copying the lines between:
162 * // C++ Operator Veneers - START
163 * and
164 * // C++ Operator Veneers - END
165 * from memento.c into a C++ file within their own project.
166 *
167 * or
168 *
169 * b) Add the following lines to a C++ file in the project:
170 * #define MEMENTO_CPP_EXTRAS_ONLY
171 * #include "memento.c"
172 *
173 * 3) For those people that would like to be able to compile memento.c
174 * with a C compiler, and provide new/delete veneers globally
175 * within their own C++ code (so avoiding the need for memento.h to
176 * be included from every file), define MEMENTO_NO_CPLUSPLUS as you
177 * build, and Memento will not provide any veneers itself, instead
178 * relying on the library user to provide them.
179 *
180 * For convenience the lines to implement such veneers can be found
181 * at the end of memento.c between:
182 * // C++ Operator Veneers - START
183 * and
184 * // C++ Operator Veneers - END
185 *
186 * Memento's interception of new/delete can be disabled at runtime
187 * by using Memento_setIgnoreNewDelete(1). Alternatively the
188 * MEMENTO_IGNORENEWDELETE environment variable can be set to 1 to
189 * achieve the same result.
190 *
191 * Both Windows and GCC provide separate new[] and delete[] operators
192 * for arrays. Apparently some systems do not. If this is the case for
193 * your system, define MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS.
194 *
195 * "libbacktrace.so failed to load"
196 *
197 * In order to give nice backtraces on unix, Memento will try to use
198 * a libbacktrace dynamic library. If it can't find it, you'll see
199 * that warning, and your backtraces won't include file/line information.
200 *
201 * To fix this you'll need to build your own libbacktrace. Don't worry
202 * it's really easy:
203 * git clone git://github.com/ianlancetaylor/libbacktrace
204 * cd libbacktrace
205 * ./configure --enable-shared
206 * make
207 *
208 * This leaves the build .so as .libs/libbacktrace.so
209 *
210 * Memento will look for this on LD_LIBRARY_PATH, or in /opt/lib/,
211 * or in /lib/, or in /usr/lib/, or in /usr/local/lib/. I recommend
212 * using /opt/lib/ as this won't conflict with anything that you
213 * get via a package manager like apt.
214 *
215 * sudo mkdir /opt
216 * sudo mkdir /opt/lib
217 * sudo cp .libs/libbacktrace.so /opt/lib/
218 */
219
220 #ifdef __cplusplus
221
222 // Avoids problems with strdup()'s throw() attribute on Linux.
223 #include <string.h>
224
225 extern "C" {
226 #endif
227
228 #ifndef MEMENTO_H
229
230 /* Include all these first, so our definitions below do
231 * not conflict with them. */
232 #include <stdlib.h>
233 #include <stdarg.h>
234 #include <string.h>
235
236 #define MEMENTO_H
237
238 #ifndef MEMENTO_UNDERLYING_MALLOC
239 #define MEMENTO_UNDERLYING_MALLOC malloc
240 #endif
241 #ifndef MEMENTO_UNDERLYING_FREE
242 #define MEMENTO_UNDERLYING_FREE free
243 #endif
244 #ifndef MEMENTO_UNDERLYING_REALLOC
245 #define MEMENTO_UNDERLYING_REALLOC realloc
246 #endif
247 #ifndef MEMENTO_UNDERLYING_CALLOC
248 #define MEMENTO_UNDERLYING_CALLOC calloc
249 #endif
250
251 #ifndef MEMENTO_MAXALIGN
252 #define MEMENTO_MAXALIGN (sizeof(int))
253 #endif
254
255 #define MEMENTO_PREFILL 0xa6
256 #define MEMENTO_POSTFILL 0xa7
257 #define MEMENTO_ALLOCFILL 0xa8
258 #define MEMENTO_FREEFILL 0xa9
259
260 int Memento_checkBlock(void *);
261 int Memento_checkAllMemory(void);
262 int Memento_check(void);
263
264 int Memento_setParanoia(int);
265 int Memento_paranoidAt(int);
266 int Memento_breakAt(int);
267 void Memento_breakOnFree(void *a);
268 void Memento_breakOnRealloc(void *a);
269 int Memento_getBlockNum(void *);
270 int Memento_find(void *a);
271 void Memento_breakpoint(void);
272 int Memento_failAt(int);
273 int Memento_failThisEvent(void);
274 void Memento_listBlocks(void);
275 void Memento_listNewBlocks(void);
276 void Memento_listLargeBlocks(void);
277 void Memento_listPhasedBlocks(void);
278 size_t Memento_setMax(size_t);
279 void Memento_stats(void);
280 void *Memento_label(void *, const char *);
281 void Memento_tick(void);
282 int Memento_setVerbose(int);
283
284 /* Terminate backtraces if we see specified function name. E.g.
285 'cfunction_call' will exclude Python interpreter functions when Python calls C
286 code. Returns 0 on success, -1 on failure (out of memory). */
287 int Memento_addBacktraceLimitFnname(const char *fnname);
288
289 /* If <atexitfin> is 0, we do not call Memento_fin() in an atexit() handler. */
290 int Memento_setAtexitFin(int atexitfin);
291
292 int Memento_setIgnoreNewDelete(int ignore);
293
294 void *Memento_malloc(size_t s);
295 void *Memento_realloc(void *, size_t s);
296 void Memento_free(void *);
297 void *Memento_calloc(size_t, size_t);
298 char *Memento_strdup(const char*);
299 #if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS)
300 int Memento_asprintf(char **ret, const char *format, ...);
301 int Memento_vasprintf(char **ret, const char *format, va_list ap);
302 #endif
303
304 void Memento_info(void *addr);
305 void Memento_listBlockInfo(void);
306 void Memento_blockInfo(void *blk);
307 void *Memento_takeByteRef(void *blk);
308 void *Memento_dropByteRef(void *blk);
309 void *Memento_takeShortRef(void *blk);
310 void *Memento_dropShortRef(void *blk);
311 void *Memento_takeIntRef(void *blk);
312 void *Memento_dropIntRef(void *blk);
313 void *Memento_takeRef(void *blk);
314 void *Memento_dropRef(void *blk);
315 void *Memento_adjustRef(void *blk, int adjust);
316 void *Memento_reference(void *blk);
317
318 int Memento_checkPointerOrNull(void *blk);
319 int Memento_checkBytePointerOrNull(void *blk);
320 int Memento_checkShortPointerOrNull(void *blk);
321 int Memento_checkIntPointerOrNull(void *blk);
322
323 void Memento_startLeaking(void);
324 void Memento_stopLeaking(void);
325
326 /* Returns number of allocation events so far. */
327 int Memento_sequence(void);
328
329 /* Returns non-zero if our process was forked by Memento squeeze. */
330 int Memento_squeezing(void);
331
332 void Memento_fin(void);
333
334 void Memento_bt(void);
335
336 void *Memento_cpp_new(size_t size);
337 void Memento_cpp_delete(void *pointer);
338 void *Memento_cpp_new_array(size_t size);
339 void Memento_cpp_delete_array(void *pointer);
340
341 void Memento_showHash(unsigned int hash);
342
343 #ifdef MEMENTO
344
345 #ifndef COMPILING_MEMENTO_C
346 #define malloc Memento_malloc
347 #define free Memento_free
348 #define realloc Memento_realloc
349 #define calloc Memento_calloc
350 #define strdup Memento_strdup
351 #if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS)
352 #define asprintf Memento_asprintf
353 #define vasprintf Memento_vasprintf
354 #endif
355 #endif
356
357 #else
358
359 #define Memento_malloc MEMENTO_UNDERLYING_MALLOC
360 #define Memento_free MEMENTO_UNDERLYING_FREE
361 #define Memento_realloc MEMENTO_UNDERLYING_REALLOC
362 #define Memento_calloc MEMENTO_UNDERLYING_CALLOC
363 #define Memento_strdup strdup
364 #if !defined(MEMENTO_GS_HACKS) && !defined(MEMENTO_MUPDF_HACKS)
365 #define Memento_asprintf asprintf
366 #define Memento_vasprintf vasprintf
367 #endif
368
369 #define Memento_checkBlock(A) 0
370 #define Memento_checkAllMemory() 0
371 #define Memento_check() 0
372 #define Memento_setParanoia(A) 0
373 #define Memento_paranoidAt(A) 0
374 #define Memento_breakAt(A) 0
375 #define Memento_breakOnFree(A) 0
376 #define Memento_breakOnRealloc(A) 0
377 #define Memento_getBlockNum(A) 0
378 #define Memento_find(A) 0
379 #define Memento_breakpoint() do {} while (0)
380 #define Memento_failAt(A) 0
381 #define Memento_failThisEvent() 0
382 #define Memento_listBlocks() do {} while (0)
383 #define Memento_listNewBlocks() do {} while (0)
384 #define Memento_listLargeBlocks() do {} while (0)
385 #define Memento_listPhasedBlocks() do {} while (0)
386 #define Memento_setMax(A) 0
387 #define Memento_stats() do {} while (0)
388 #define Memento_label(A,B) (A)
389 #define Memento_info(A) do {} while (0)
390 #define Memento_listBlockInfo() do {} while (0)
391 #define Memento_blockInfo(A) do {} while (0)
392 #define Memento_takeByteRef(A) (A)
393 #define Memento_dropByteRef(A) (A)
394 #define Memento_takeShortRef(A) (A)
395 #define Memento_dropShortRef(A) (A)
396 #define Memento_takeIntRef(A) (A)
397 #define Memento_dropIntRef(A) (A)
398 #define Memento_takeRef(A) (A)
399 #define Memento_dropRef(A) (A)
400 #define Memento_adjustRef(A,V) (A)
401 #define Memento_reference(A) (A)
402 #define Memento_checkPointerOrNull(A) 0
403 #define Memento_checkBytePointerOrNull(A) 0
404 #define Memento_checkShortPointerOrNull(A) 0
405 #define Memento_checkIntPointerOrNull(A) 0
406 #define Memento_setIgnoreNewDelete(v) 0
407
408 #define Memento_tick() do {} while (0)
409 #define Memento_startLeaking() do {} while (0)
410 #define Memento_stopLeaking() do {} while (0)
411 #define Memento_fin() do {} while (0)
412 #define Memento_bt() do {} while (0)
413 #define Memento_sequence() (0)
414 #define Memento_squeezing() (0)
415 #define Memento_setVerbose(A) (A)
416 #define Memento_addBacktraceLimitFnname(A) (0)
417 #define Memento_setAtexitFin(atexitfin) (0)
418
419 #endif /* MEMENTO */
420
421 #ifdef __cplusplus
422 }
423 #endif
424
425 #endif /* MEMENTO_H */