1 /* This file is part of XEmacs.
3 XEmacs is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2, or (at your option) any
8 XEmacs is distributed in the hope that it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 You should have received a copy of the GNU General Public License
14 along with XEmacs; see the file COPYING. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA. */
18 /* Synched up with: Not in FSF. */
20 /* Debugging hooks for malloc. */
22 /* These hooks work with gmalloc to catch allocation errors.
23 In particular, the following is trapped:
25 * Freeing the same pointer twice.
26 * Trying to free a pointer not returned by malloc.
27 * Trying to realloc a pointer not returned by malloc.
29 In addition, every word of every block freed is set to
30 0xdeadbeef. This causes many uses of freed storage to be
31 trapped or recognized.
33 When you use this, the storage used by the last FREE_QUEUE_LIMIT
34 calls to free() is not recycled. When you call free for the Nth
35 time, the (N - FREE_QUEUE_LIMIT)'th block is actually recycled.
37 For these last FREE_QUEUE_LIMIT calls to free() a backtrace is
38 saved showing where it was called from. The function
39 find_backtrace() is provided here to be called from GDB with a
40 pointer (such as would be passed to free()) as argument, e.g.
41 (gdb) p/a *find_backtrace (0x234000). If SAVE_ARGS is defined,
42 the first three arguments to each function are saved as well as the
45 If UNMAPPED_FREE is defined, instead of setting every word of freed
46 storage to 0xdeadbeef, every call to malloc goes on its own page(s).
47 When free() is called, the block is read and write protected. This
48 is very useful when debugging, since it usually generates a bus error
49 when the deadbeef hack might only cause some garbage to be printed.
50 However, this is too slow for everyday use, since it takes an enormous
54 Some other features that would be useful are:
56 * Checking for storage leaks.
57 This could be done by a GC-like facility that would scan the data
58 segment looking for pointers to allocated storage and tell you
59 about those that are no longer referenced. This could be invoked
60 at any time. Another possibility is to report on what allocated
61 storage is still in use when the process is exited. Typically
62 there will be a large amount, so this might not be very useful.
69 void *malloc (size_t);
72 #if !defined(HAVE_LIBMCHECK)
79 #include <sys/param.h>
80 #define ROUND_UP_TO_PAGE(i) (((i) + PAGEOFFSET) & PAGEMASK)
83 #include <sys/types.h>
85 /* System function prototypes don't belong in C source files */
86 /* extern void free (void *); */
88 static struct hash_table *pointer_table;
90 extern void (*__free_hook) (void *);
91 extern void *(*__malloc_hook) (size_t);
93 static void *check_malloc (size_t);
95 typedef void (*fun_ptr) (void);
97 /* free_queue is not too useful without backtrace logging */
98 #define FREE_QUEUE_LIMIT 1
99 #define TRACE_LIMIT 20
110 unsigned long length;
113 static free_queue_entry free_queue[FREE_QUEUE_LIMIT];
115 static int current_free;
117 static int strict_free_check;
120 check_free (void *ptr)
125 pointer_table = make_hash_table (max (100, FREE_QUEUE_LIMIT * 2));
130 unsigned long rounded_up_size;
133 EMACS_INT present = (EMACS_INT) gethash (ptr, pointer_table,
134 (const void **) &size);
138 /* This can only happen if you try to free something that didn't
140 #if !defined(__linux__)
141 /* I originally wrote: "There's really no need to drop core."
142 I have seen the error of my ways. -slb */
143 if (strict_free_check)
146 printf("Freeing unmalloc'ed memory at %p\n", ptr);
147 __free_hook = check_free;
148 __malloc_hook = check_malloc;
154 /* This happens when you free twice */
155 #if !defined(__linux__)
156 /* See above comment. */
157 if (strict_free_check)
160 printf("Freeing %p twice\n", ptr);
161 __free_hook = check_free;
162 __malloc_hook = check_malloc;
166 puthash (ptr, (void *)-size, pointer_table);
168 /* Round up size to an even number of pages. */
169 rounded_up_size = ROUND_UP_TO_PAGE (size);
170 /* Protect the pages freed from all access */
171 if (strict_free_check)
172 mprotect (ptr, rounded_up_size, PROT_NONE);
174 /* Set every word in the block to 0xdeadbeef */
175 if (strict_free_check)
177 unsigned long long_length = (size + (sizeof (long) - 1))
181 for (i = 0; i < long_length; i++)
182 ((unsigned long *) ptr)[i] = 0xdeadbeef;
185 free_queue[current_free].address = ptr;
186 free_queue[current_free].length = size;
189 if (current_free >= FREE_QUEUE_LIMIT)
191 /* Really free this if there's something there */
193 void *old = free_queue[current_free].address;
198 unsigned long old_len = free_queue[current_free].length;
200 mprotect (old, old_len, PROT_READ | PROT_WRITE | PROT_EXEC);
203 remhash (old, pointer_table);
207 __free_hook = check_free;
208 __malloc_hook = check_malloc;
215 check_malloc (size_t size)
217 size_t rounded_up_size;
228 /* Round up to an even number of pages. */
229 rounded_up_size = ROUND_UP_TO_PAGE (size);
231 rounded_up_size = size;
233 result = malloc (rounded_up_size);
235 pointer_table = make_hash_table (FREE_QUEUE_LIMIT * 2);
236 puthash (result, (void *)size, pointer_table);
237 __free_hook = check_free;
238 __malloc_hook = check_malloc;
243 extern void *(*__realloc_hook) (void *, size_t);
248 #define MIN(A, B) ((A) < (B) ? (A) : (B))
250 /* Don't optimize realloc */
253 check_realloc (void * ptr, size_t size)
257 void *result = malloc (size);
259 if (!ptr) return result;
260 present = (EMACS_INT) gethash (ptr, pointer_table, (const void **) &old_size);
263 /* This can only happen by reallocing a pointer that didn't
265 #if !defined(__linux__)
266 /* see comment in check_free(). */
269 printf("Realloc'ing unmalloc'ed pointer at %p\n", ptr);
274 memcpy (result, ptr, MIN (size, old_size));
280 void enable_strict_free_check (void);
282 enable_strict_free_check (void)
284 strict_free_check = 1;
287 void disable_strict_free_check (void);
289 disable_strict_free_check (void)
291 strict_free_check = 0;
294 /* Note: All BLOCK_INPUT stuff removed from this file because it's
295 completely gone in XEmacs */
298 block_input_malloc (size_t size);
301 block_input_free (void* ptr)
306 __free_hook = block_input_free;
307 __malloc_hook = block_input_malloc;
311 block_input_malloc (size_t size)
316 result = malloc (size);
317 __free_hook = block_input_free;
318 __malloc_hook = block_input_malloc;
324 block_input_realloc (void* ptr, size_t size)
330 result = realloc (ptr, size);
331 __free_hook = block_input_free;
332 __malloc_hook = block_input_malloc;
333 __realloc_hook = block_input_realloc;
339 void disable_free_hook (void);
341 disable_free_hook (void)
343 __free_hook = block_input_free;
344 __malloc_hook = block_input_malloc;
345 __realloc_hook = block_input_realloc;
349 init_free_hook (void)
351 __free_hook = check_free;
352 __malloc_hook = check_malloc;
353 __realloc_hook = check_realloc;
355 strict_free_check = 1;
358 void really_free_one_entry (void *, int, int *);
360 DEFUN ("really-free", Freally_free, 0, 1, "P", /*
361 Actually free the storage held by the free() debug hook.
362 A no-op if the free hook is disabled.
367 Lisp_Object lisp_count[2];
369 if ((__free_hook != 0) && pointer_table)
374 maphash ((maphash_function)really_free_one_entry,
375 pointer_table, (void *)&count);
376 memset (free_queue, 0, sizeof (free_queue_entry) * FREE_QUEUE_LIMIT);
378 __free_hook = check_free;
379 XSETINT (lisp_count[0], count[0]);
380 XSETINT (lisp_count[1], count[1]);
381 return Fcons (lisp_count[0], lisp_count[1]);
384 return Fcons (make_int (0), make_int (0));
388 really_free_one_entry (void *key, int contents, int *countp)
394 mprotect (key, -contents, PROT_READ | PROT_WRITE | PROT_EXEC);
396 remhash (key, pointer_table);
398 countp[1] += -contents;
403 syms_of_free_hook (void)
405 DEFSUBR (Freally_free);
409 void (*__free_hook)(void *) = check_free;
410 void *(*__malloc_hook)(size_t) = check_malloc;
411 void *(*__realloc_hook)(void *, size_t) = check_realloc;
414 #endif /* !defined(HAVE_LIBMCHECK) */
416 #if defined(DEBUG_INPUT_BLOCKING) || defined (DEBUG_GCPRO)
418 /* Note: There is no more input blocking in XEmacs */
420 block_type, unblock_type, totally_type,
421 gcpro1_type, gcpro2_type, gcpro3_type, gcpro4_type, gcpro5_type,
425 struct block_input_history_struct
433 typedef struct block_input_history_struct block_input_history;
435 #endif /* DEBUG_INPUT_BLOCKING || DEBUG_GCPRO */
437 #ifdef DEBUG_INPUT_BLOCKING
441 #define BLHISTLIMIT 1000
443 block_input_history blhist[BLHISTLIMIT];
445 note_block_input (char *file, int line)
447 note_block (file, line, block_type);
448 if (interrupt_input_blocked > 2) ABORT();
451 note_unblock_input (char* file, int line)
453 note_block (file, line, unblock_type);
456 note_totally_unblocked (char* file, int line)
458 note_block (file, line, totally_type);
461 note_block (char *file, int line, blocktype type)
463 blhist[blhistptr].file = file;
464 blhist[blhistptr].line = line;
465 blhist[blhistptr].type = type;
466 blhist[blhistptr].value = interrupt_input_blocked;
469 if (blhistptr >= BLHISTLIMIT)
473 #endif /* DEBUG_INPUT_BLOCKING */
479 #define GCPROHISTLIMIT 1000
480 block_input_history gcprohist[GCPROHISTLIMIT];
483 log_gcpro (char *file, int line, struct gcpro *value, blocktype type)
485 if (type == ungcpro_type)
487 if (value == gcprolist) goto OK;
488 if (! gcprolist) ABORT ();
489 if (value == gcprolist->next) goto OK;
490 if (! gcprolist->next) ABORT ();
491 if (value == gcprolist->next->next) goto OK;
492 if (! gcprolist->next->next) ABORT ();
493 if (value == gcprolist->next->next->next) goto OK;
494 if (! gcprolist->next->next->next) ABORT ();
495 if (value == gcprolist->next->next->next->next) goto OK;
499 gcprohist[gcprohistptr].file = file;
500 gcprohist[gcprohistptr].line = line;
501 gcprohist[gcprohistptr].type = type;
502 gcprohist[gcprohistptr].value = (int) value;
504 if (gcprohistptr >= GCPROHISTLIMIT)
509 debug_gcpro1 (char *file, int line, struct gcpro *gcpro1, Lisp_Object *var)
511 gcpro1->next = gcprolist; gcpro1->var = var; gcpro1->nvars = 1;
513 log_gcpro (file, line, gcpro1, gcpro1_type);
517 debug_gcpro2 (char *file, int line, struct gcpro *gcpro1, struct gcpro *gcpro2,
518 Lisp_Object *var1, Lisp_Object *var2)
520 gcpro1->next = gcprolist; gcpro1->var = var1; gcpro1->nvars = 1;
521 gcpro2->next = gcpro1; gcpro2->var = var2; gcpro2->nvars = 1;
523 log_gcpro (file, line, gcpro2, gcpro2_type);
527 debug_gcpro3 (char *file, int line, struct gcpro *gcpro1, struct gcpro *gcpro2,
528 struct gcpro *gcpro3, Lisp_Object *var1, Lisp_Object *var2,
531 gcpro1->next = gcprolist; gcpro1->var = var1; gcpro1->nvars = 1;
532 gcpro2->next = gcpro1; gcpro2->var = var2; gcpro2->nvars = 1;
533 gcpro3->next = gcpro2; gcpro3->var = var3; gcpro3->nvars = 1;
535 log_gcpro (file, line, gcpro3, gcpro3_type);
539 debug_gcpro4 (char *file, int line, struct gcpro *gcpro1, struct gcpro *gcpro2,
540 struct gcpro *gcpro3, struct gcpro *gcpro4, Lisp_Object *var1,
541 Lisp_Object *var2, Lisp_Object *var3, Lisp_Object *var4)
543 log_gcpro (file, line, gcpro4, gcpro4_type);
544 gcpro1->next = gcprolist; gcpro1->var = var1; gcpro1->nvars = 1;
545 gcpro2->next = gcpro1; gcpro2->var = var2; gcpro2->nvars = 1;
546 gcpro3->next = gcpro2; gcpro3->var = var3; gcpro3->nvars = 1;
547 gcpro4->next = gcpro3; gcpro4->var = var4; gcpro4->nvars = 1;
552 debug_gcpro5 (char *file, int line, struct gcpro *gcpro1, struct gcpro *gcpro2,
553 struct gcpro *gcpro3, struct gcpro *gcpro4, struct gcpro *gcpro5,
554 Lisp_Object *var1, Lisp_Object *var2, Lisp_Object *var3,
555 Lisp_Object *var4, Lisp_Object *var5)
557 log_gcpro (file, line, gcpro5, gcpro5_type);
558 gcpro1->next = gcprolist; gcpro1->var = var1; gcpro1->nvars = 1;
559 gcpro2->next = gcpro1; gcpro2->var = var2; gcpro2->nvars = 1;
560 gcpro3->next = gcpro2; gcpro3->var = var3; gcpro3->nvars = 1;
561 gcpro4->next = gcpro3; gcpro4->var = var4; gcpro4->nvars = 1;
562 gcpro5->next = gcpro4; gcpro5->var = var5; gcpro5->nvars = 1;
567 debug_ungcpro (char *file, int line, struct gcpro *gcpro1)
569 log_gcpro (file, line, gcpro1, ungcpro_type);
570 gcprolist = gcpro1->next;
574 /* To be called from the debugger */
575 void show_gcprohist (void);
577 show_gcprohist (void)
580 for (i = 0, j = gcprohistptr;
584 if (j >= GCPROHISTLIMIT)
586 printf ("%3d %s %d %s 0x%x\n",
587 j, gcprohist[j].file, gcprohist[j].line,
588 (gcprohist[j].type == gcpro1_type ? "GCPRO1" :
589 gcprohist[j].type == gcpro2_type ? "GCPRO2" :
590 gcprohist[j].type == gcpro3_type ? "GCPRO3" :
591 gcprohist[j].type == gcpro4_type ? "GCPRO4" :
592 gcprohist[j].type == gcpro5_type ? "GCPRO5" :
593 gcprohist[j].type == ungcpro_type ? "UNGCPRO" : "???"),
599 #endif /* DEBUG_GCPRO */