[v2] malloc: Add realloc test.

Message ID 5208A192.4040409@linaro.org
State Superseded
Headers show

Commit Message

Will Newton Aug. 12, 2013, 8:49 a.m.
The current tests don't test the functionality of realloc in detail.
Add a new test for realloc that exercises some of the corner cases
that are not otherwise tested.

ChangeLog:

2013-08-07  Will Newton  <will.newton@linaro.org>

	* malloc/Makefile: Add tst-realloc to tests.
	* malloc/tst-realloc.c: New file.
---
 malloc/Makefile      |   3 +-
 malloc/tst-realloc.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+), 1 deletion(-)
 create mode 100644 malloc/tst-realloc.c

Changes in v2:
 - Use test-skeleton.c framework.

Comments

Andreas Jaeger Aug. 12, 2013, 9:13 a.m. | #1
On 08/12/2013 10:49 AM, Will Newton wrote:
> The current tests don't test the functionality of realloc in detail.
> Add a new test for realloc that exercises some of the corner cases
> that are not otherwise tested.
> 
> ChangeLog:
> 
> 2013-08-07  Will Newton  <will.newton@linaro.org>
> 
> 	* malloc/Makefile: Add tst-realloc to tests.
> 	* malloc/tst-realloc.c: New file.

Looks fine to me. Note that we're in 2.18 freeze right now, once 2.19
opens up, this can go in,

Thanks,
Andreas
Joseph Myers Aug. 18, 2013, 7:26 p.m. | #2
On Mon, 12 Aug 2013, Will Newton wrote:

> The current tests don't test the functionality of realloc in detail.
> Add a new test for realloc that exercises some of the corner cases
> that are not otherwise tested.

Given the confusion that has surrounded corner cases of realloc, could you 
clarify (in comments in the test) how exactly the requirements being 
tested are traced to C90, C99, C11 and POSIX (or to existing glibc 
practice, as applicable)?  (It appears you aren't testing the particularly 
problematic cases with size 0 - see 
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_400.htm> - but 
explicitly saying what tests trace to what standard requirements still 
seems a good idea.  Maybe a separate test should be added to verify as far 
as possible that glibc stays compatible with existing glibc practice for 
size 0.)

Patch

diff --git a/malloc/Makefile b/malloc/Makefile
index 0fe31a4..b16dac8 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -25,7 +25,8 @@  all:
 dist-headers := malloc.h
 headers := $(dist-headers) obstack.h mcheck.h
 tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
-	 tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 tst-malloc-usable
+	 tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \
+	 tst-malloc-usable tst-realloc
 test-srcs = tst-mtrace

 routines = malloc morecore mcheck mtrace obstack
diff --git a/malloc/tst-realloc.c b/malloc/tst-realloc.c
new file mode 100644
index 0000000..7f61075
--- /dev/null
+++ b/malloc/tst-realloc.c
@@ -0,0 +1,126 @@ 
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C 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 C 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 C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+static int errors = 0;
+
+static void
+merror (const char *msg)
+{
+  ++errors;
+  printf ("Error: %s\n", msg);
+}
+
+static int
+do_test (void)
+{
+  void *p;
+  unsigned char *c;
+  int save, i, ok;
+
+  errno = 0;
+
+  p = realloc (NULL, -1);
+  save = errno;
+
+  if (p != NULL)
+    merror ("realloc (NULL, -1) succeeded.");
+
+  if (p == NULL && save != ENOMEM)
+    merror ("errno is not set correctly");
+
+  p = realloc (NULL, 10);
+  if (p == NULL)
+    merror ("realloc (NULL, 10) failed.");
+
+  free (p);
+
+  p = calloc (20, 1);
+  if (p == NULL)
+    merror ("calloc (20, 1) failed.");
+
+  /* Check increasing size preserves contents.  */
+  p = realloc (p, 200);
+  if (p == NULL)
+    merror ("realloc (p, 200) failed.");
+
+  c = p;
+  ok = 1;
+
+  for (i = 0; i < 20; i++)
+    {
+      if (c[i] != 0)
+	ok = 0;
+    }
+
+  if (ok == 0)
+	merror ("first 20 bytes were not cleared");
+
+  free (p);
+
+  /* Check realloc(NULL, ...) works correctly.  */
+  p = realloc (NULL, 100);
+  if (p == NULL)
+    merror ("realloc (NULL, 100) failed.");
+
+  memset (p, 0xff, 100);
+
+  /* Check decreasing size preserves contents.  */
+  p = realloc (p, 16);
+  if (p == NULL)
+    merror ("realloc (p, 16) failed.");
+
+  c = p;
+  ok = 1;
+
+  for (i = 0; i < 16; i++)
+    {
+      if (c[i] != 0xff)
+	ok = 0;
+    }
+
+  if (ok == 0)
+	merror ("first 16 bytes were not correct");
+
+  /* Check failed realloc leaves original untouched.  */
+  c = realloc (p, -1);
+  if (c != NULL)
+    merror ("realloc (p, -1) succeeded.");
+
+  c = p;
+  ok = 1;
+
+  for (i = 0; i < 16; i++)
+    {
+      if (c[i] != 0xff)
+	ok = 0;
+    }
+
+  if (ok == 0)
+	merror ("first 16 bytes were not correct after failed realloc");
+
+  free (p);
+
+  return errors != 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"