Mercurial > hgrepos > Python2 > PyMuPDF
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 */ |
