[BACK]Return to tal-debug.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp

Annotation of OpenXM_contrib/gmp/tal-debug.c, Revision 1.1.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>