diff options
author | zimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2009-11-20 15:04:07 +0000 |
---|---|---|
committer | zimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2009-11-20 15:04:07 +0000 |
commit | c1bce31b9e8704cac4bc857ab13512f45c8e5bc8 (patch) | |
tree | e32ab54bf3efd790ad5534bacf7d57aa59c19ac0 | |
parent | ea0af5971c3e88793a5db1a4582d2059cabd2ec6 (diff) | |
download | mpc-c1bce31b9e8704cac4bc857ab13512f45c8e5bc8.tar.gz |
added mechanism (copied from GNU MPFR 2.4.1) to check memory
-> found one bug in atan (one variable was init two times)
and one problem in tio_str.c (some variables were init before test_start)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@724 211d60ee-9f03-0410-a15a-8952a2c7a4e4
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/memory.c | 196 | ||||
-rw-r--r-- | tests/mpc-tests.h | 2 | ||||
-rw-r--r-- | tests/random.c | 3 | ||||
-rw-r--r-- | tests/tio_str.c | 6 |
5 files changed, 205 insertions, 4 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 7bf625d..10c1958 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -13,7 +13,7 @@ ttan ttanh tui_div tui_ui_sub tget_version check_LTLIBRARIES=libmpc-tests.la libmpc_tests_la_SOURCES=mpc-tests.h random.c tgeneric.c read_data.c \ -comparisons.c +comparisons.c memory.c EXTRA_DIST = abs.dat acos.dat acosh.dat asin.dat asinh.dat atan.dat atanh.dat \ add.dat add_fr.dat arg.dat conj.dat cos.dat cosh.dat \ diff --git a/tests/memory.c b/tests/memory.c new file mode 100644 index 0000000..1af985f --- /dev/null +++ b/tests/memory.c @@ -0,0 +1,196 @@ +/* Memory allocation used during tests. + +Copyright 2001, 2002, 2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Contributed by the Arenaire and Cacao projects, INRIA. + +This file is part of the GNU MPFR Library (version 2.4.1). + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +MA 02110-1301, USA. */ + +/* Note: this file comes from GMP's tests/memory.c */ + +#include <stdio.h> +#include <stdlib.h> /* for abort */ +#include <limits.h> +#include "gmp.h" + +#define __gmp_default_allocate malloc +#define __gmp_default_reallocate(p,old,new) realloc(p,new) +#define __gmp_default_free(p,size) free(p) + +/* Each block allocated is a separate malloc, for the benefit of a redzoning + malloc debugger during development or when bug hunting. + + Sizes passed when reallocating or freeing are checked (the default + routines don't care about these). + + Memory leaks are checked by requiring that all blocks have been freed + when tests_memory_end() is called. Test programs must be sure to have + "clear"s for all temporary variables used. */ + +struct header { + void *ptr; + size_t size; + struct header *next; +}; + +static struct header *tests_memory_list; + +/* Return a pointer to a pointer to the found block (so it can be updated + when unlinking). */ +static struct header ** +tests_memory_find (void *ptr) +{ + struct header **hp; + + for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next)) + if ((*hp)->ptr == ptr) + return hp; + + return NULL; +} + +/* +static int +tests_memory_valid (void *ptr) +{ + return (tests_memory_find (ptr) != NULL); +} +*/ + +static void * +tests_allocate (size_t size) +{ + struct header *h; + + if (size == 0) + { + printf ("tests_allocate(): attempt to allocate 0 bytes\n"); + abort (); + } + + h = (struct header *) __gmp_default_allocate (sizeof (*h)); + h->next = tests_memory_list; + tests_memory_list = h; + + h->size = size; + h->ptr = __gmp_default_allocate (size); + return h->ptr; +} + +static void * +tests_reallocate (void *ptr, size_t old_size, size_t new_size) +{ + struct header **hp, *h; + + if (new_size == 0) + { + printf ("tests_reallocate(): attempt to reallocate 0x%lX to 0 bytes\n", + (unsigned long) ptr); + abort (); + } + + hp = tests_memory_find (ptr); + if (hp == NULL) + { + printf ("tests_reallocate(): attempt to reallocate bad pointer 0x%lX\n", + (unsigned long) ptr); + abort (); + } + h = *hp; + + if (h->size != old_size) + { + /* Note: we should use the standard %zu to print sizes, but + this is not supported by old C implementations. */ + printf ("tests_reallocate(): bad old size %lu, should be %lu\n", + (unsigned long) old_size, (unsigned long) h->size); + abort (); + } + + h->size = new_size; + h->ptr = __gmp_default_reallocate (ptr, old_size, new_size); + return h->ptr; +} + +static struct header ** +tests_free_find (void *ptr) +{ + struct header **hp = tests_memory_find (ptr); + if (hp == NULL) + { + printf ("tests_free(): attempt to free bad pointer 0x%lX\n", + (unsigned long) ptr); + abort (); + } + return hp; +} + +static void +tests_free_nosize (void *ptr) +{ + struct header **hp = tests_free_find (ptr); + struct header *h = *hp; + + *hp = h->next; /* unlink */ + + __gmp_default_free (ptr, h->size); + __gmp_default_free (h, sizeof (*h)); +} + +static void +tests_free (void *ptr, size_t size) +{ + struct header **hp = tests_free_find (ptr); + struct header *h = *hp; + + if (h->size != size) + { + /* Note: we should use the standard %zu to print sizes, but + this is not supported by old C implementations. */ + printf ("tests_free(): bad size %lu, should be %lu\n", + (unsigned long) size, (unsigned long) h->size); + abort (); + } + + tests_free_nosize (ptr); +} + +void +tests_memory_start (void) +{ + tests_memory_list = NULL; + mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free); +} + +void +tests_memory_end (void) +{ + if (tests_memory_list != NULL) + { + struct header *h; + unsigned count; + + printf ("tests_memory_end(): not all memory freed\n"); + + count = 0; + for (h = tests_memory_list; h != NULL; h = h->next) + count++; + + printf (" %u blocks remaining\n", count); + abort (); + } +} diff --git a/tests/mpc-tests.h b/tests/mpc-tests.h index d436df9..24eef36 100644 --- a/tests/mpc-tests.h +++ b/tests/mpc-tests.h @@ -185,6 +185,8 @@ void read_int (FILE *fp, int *n, const char *name); size_t read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name); void read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign); void read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks); +void tests_memory_start (void); +void tests_memory_end (void); #define TERNARY_NOT_CHECKED 255 /* special value to indicate that the ternary value is not checked */ diff --git a/tests/random.c b/tests/random.c index 821f68b..ed31476 100644 --- a/tests/random.c +++ b/tests/random.c @@ -49,6 +49,8 @@ test_start (void) char *environment_seed; unsigned long seed; + tests_memory_start (); + if (rands_initialized) { fprintf (stderr, @@ -97,6 +99,7 @@ test_end (void) gmp_randclear (rands); } mpfr_free_cache (); + tests_memory_end (); } /* Set z to a non zero value random value with absolute values of Re(z) and diff --git a/tests/tio_str.c b/tests/tio_str.c index 99eb989..e1a040f 100644 --- a/tests/tio_str.c +++ b/tests/tio_str.c @@ -213,13 +213,13 @@ main (void) mpc_t z, x; mp_prec_t prec; + test_start (); + mpc_init2 (z, 1000); mpc_init2 (x, 1000); check_file ("inp_str.dat"); - test_start(); - for (prec = 2; prec <= 1000; prec+=7) { mpc_set_prec (z, prec); @@ -249,7 +249,7 @@ main (void) mpc_clear (z); mpc_clear (x); - test_end(); + test_end (); return 0; } |