Annotation of OpenXM_contrib/gmp/tal-debug.c, Revision 1.1
1.1 ! ohara 1: /* TMP_ALLOC routines for debugging.
! 2:
! 3: Copyright 2000, 2001 Free Software Foundation, Inc.
! 4:
! 5: This file is part of the GNU MP Library.
! 6:
! 7: The GNU MP Library is free software; you can redistribute it and/or modify
! 8: it under the terms of the GNU Lesser General Public License as published by
! 9: the Free Software Foundation; either version 2.1 of the License, or (at your
! 10: option) any later version.
! 11:
! 12: The GNU MP Library is distributed in the hope that it will be useful, but
! 13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
! 15: License for more details.
! 16:
! 17: You should have received a copy of the GNU Lesser General Public License
! 18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! 19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 20: MA 02111-1307, USA. */
! 21:
! 22: #include <stdio.h>
! 23: #include "gmp.h"
! 24: #include "gmp-impl.h"
! 25:
! 26:
! 27: /* This method aims to help a malloc debugger find problems. A linked list
! 28: of allocated block is kept for TMP_FREE to release. This is reentrant
! 29: and thread safe.
! 30:
! 31: Each TMP_ALLOC is a separate malloced block, so redzones or sentinels
! 32: applied by a malloc debugger either above or below can guard against
! 33: accesses outside the allocated area.
! 34:
! 35: A marker is a "struct tmp_debug_t *" so that TMP_DECL can initialize it
! 36: to NULL and we can detect TMP_ALLOC without TMP_MARK.
! 37:
! 38: It will work to realloc an MPZ_TMP_INIT variable, but when TMP_FREE comes
! 39: to release the memory it will have the old size, thereby triggering an
! 40: error from tests/memory.c.
! 41:
! 42: Possibilities:
! 43:
! 44: It'd be possible to keep a global list of active "struct tmp_debug_t"
! 45: records, so at the end of a program any TMP leaks could be printed. But
! 46: if only a couple of routines are under test at any one time then the
! 47: likely culprit should be easy enough to spot. */
! 48:
! 49:
! 50: void
! 51: __gmp_tmp_debug_mark (const char *file, int line,
! 52: struct tmp_debug_t **markp, struct tmp_debug_t *mark,
! 53: const char *decl_name, const char *mark_name)
! 54: {
! 55: if (strcmp (mark_name, decl_name) != 0)
! 56: {
! 57: __gmp_assert_header (file, line);
! 58: fprintf (stderr, "GNU MP: TMP_MARK(%s) but TMP_DECL(%s) is in scope\n",
! 59: mark_name, decl_name);
! 60: abort ();
! 61: }
! 62:
! 63: if (*markp != NULL)
! 64: {
! 65: __gmp_assert_header (file, line);
! 66: fprintf (stderr, "GNU MP: Repeat of TMP_MARK(%s)\n", mark_name);
! 67: if (mark->file != NULL && mark->file[0] != '\0' && mark->line != -1)
! 68: {
! 69: __gmp_assert_header (mark->file, mark->line);
! 70: fprintf (stderr, "previous was here\n");
! 71: }
! 72: abort ();
! 73: }
! 74:
! 75: *markp = mark;
! 76: mark->file = file;
! 77: mark->line = line;
! 78: mark->list = NULL;
! 79: }
! 80:
! 81: void *
! 82: __gmp_tmp_debug_alloc (const char *file, int line, int dummy,
! 83: struct tmp_debug_t **markp,
! 84: const char *decl_name, size_t size)
! 85: {
! 86: struct tmp_debug_t *mark = *markp;
! 87: struct tmp_debug_entry_t *p;
! 88:
! 89: ASSERT_ALWAYS (size >= 1);
! 90:
! 91: if (mark == NULL)
! 92: {
! 93: __gmp_assert_header (file, line);
! 94: fprintf (stderr, "GNU MP: TMP_ALLOC without TMP_MARK(%s)\n", decl_name);
! 95: abort ();
! 96: }
! 97:
! 98: p = __GMP_ALLOCATE_FUNC_TYPE (1, struct tmp_debug_entry_t);
! 99: p->size = size;
! 100: p->block = (*__gmp_allocate_func) (size);
! 101: p->next = mark->list;
! 102: mark->list = p;
! 103: return p->block;
! 104: }
! 105:
! 106: void
! 107: __gmp_tmp_debug_free (const char *file, int line, int dummy,
! 108: struct tmp_debug_t **markp,
! 109: const char *decl_name, const char *free_name)
! 110: {
! 111: struct tmp_debug_t *mark = *markp;
! 112: struct tmp_debug_entry_t *p, *next;
! 113:
! 114: if (mark == NULL)
! 115: {
! 116: __gmp_assert_header (file, line);
! 117: fprintf (stderr, "GNU MP: TMP_FREE(%s) without TMP_MARK(%s)\n",
! 118: free_name, decl_name);
! 119: abort ();
! 120: }
! 121:
! 122: if (strcmp (free_name, decl_name) != 0)
! 123: {
! 124: __gmp_assert_header (file, line);
! 125: fprintf (stderr, "GNU MP: TMP_FREE(%s) when TMP_DECL(%s) is in scope\n",
! 126: free_name, decl_name);
! 127: abort ();
! 128: }
! 129:
! 130: p = mark->list;
! 131: while (p != NULL)
! 132: {
! 133: next = p->next;
! 134: (*__gmp_free_func) (p->block, p->size);
! 135: __GMP_FREE_FUNC_TYPE (p, 1, struct tmp_debug_entry_t);
! 136: p = next;
! 137: }
! 138:
! 139: *markp = NULL;
! 140: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>