summaryrefslogtreecommitdiff
path: root/test/malloc
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@uclibc-ng.org>2016-10-24 20:22:12 +0200
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-10-24 20:22:12 +0200
commit7988979a722b4cdf287b2093956a76a3f19b9897 (patch)
treed35e251d0472ceca55a2eef61cff261c8ee68fab /test/malloc
add uClibc-ng test directory
Diffstat (limited to 'test/malloc')
-rw-r--r--test/malloc/Makefile8
-rw-r--r--test/malloc/Makefile.in16
-rw-r--r--test/malloc/malloc-standard-alignment.c42
-rw-r--r--test/malloc/malloc.c81
-rw-r--r--test/malloc/mallocbug.c67
-rw-r--r--test/malloc/realloc-can-shrink.c17
-rw-r--r--test/malloc/realloc0.c13
-rw-r--r--test/malloc/testmalloc.c101
-rw-r--r--test/malloc/time_malloc.c62
-rw-r--r--test/malloc/tst-asprintf.c27
-rw-r--r--test/malloc/tst-calloc.c127
-rw-r--r--test/malloc/tst-malloc.c72
-rw-r--r--test/malloc/tst-mallocfork.c51
-rw-r--r--test/malloc/tst-mcheck.c95
-rw-r--r--test/malloc/tst-obstack.c104
-rw-r--r--test/malloc/tst-valloc.c23
16 files changed, 906 insertions, 0 deletions
diff --git a/test/malloc/Makefile b/test/malloc/Makefile
new file mode 100644
index 0000000..97c424b
--- /dev/null
+++ b/test/malloc/Makefile
@@ -0,0 +1,8 @@
+# uClibc malloc tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+top_builddir=../../
+top_srcdir=../../
+include ../Rules.mak
+-include Makefile.in
+include ../Test.mak
diff --git a/test/malloc/Makefile.in b/test/malloc/Makefile.in
new file mode 100644
index 0000000..875a849
--- /dev/null
+++ b/test/malloc/Makefile.in
@@ -0,0 +1,16 @@
+# uClibc malloc tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+TESTS_DISABLED := time_malloc
+
+ifneq ($(UCLIBC_SUSV2_LEGACY),y)
+TESTS_DISABLED += tst-valloc
+endif
+
+ifneq ($(UCLIBC_HAS_OBSTACK),y)
+TESTS_DISABLED += tst-obstack
+endif
+
+ifneq ($(MALLOC_STANDARD),y)
+TESTS_DISABLED += tst-asprintf
+endif
diff --git a/test/malloc/malloc-standard-alignment.c b/test/malloc/malloc-standard-alignment.c
new file mode 100644
index 0000000..71e5023
--- /dev/null
+++ b/test/malloc/malloc-standard-alignment.c
@@ -0,0 +1,42 @@
+/* exercise a bug found in malloc-standard when alignment
+ * values are out of whack and cause a small overflow into
+ * actual user data.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#define ok(p) ((void*)p > (void*)0x1000)
+#define x \
+ do { \
+ printf("%i: phead = %p, phead->link @ %p = %p %s\n", \
+ __LINE__, phead, \
+ ok(phead) ? &phead->link : 0, \
+ ok(phead) ? phead->link : 0, \
+ ok(phead) ? phead->link == 0 ? "" : "!!!!!!!!!!!" : ""); \
+ if (phead->link != NULL) exit(1); \
+ } while (0);
+
+struct llist_s {
+ void *data;
+ struct llist_s *link;
+} *phead;
+
+int main(int argc, char *argv[])
+{
+ char *line, *reg;
+
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+
+ phead = malloc(sizeof(*phead));
+ phead->link = NULL;
+
+x line = malloc(80);
+x line = realloc(line, 2);
+x reg = malloc(32);
+x free(line);
+
+x return 0;
+}
diff --git a/test/malloc/malloc.c b/test/malloc/malloc.c
new file mode 100644
index 0000000..ca7c5f9
--- /dev/null
+++ b/test/malloc/malloc.c
@@ -0,0 +1,81 @@
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#define N_PTRS 1000
+#define N_ALLOCS 10000
+#define MAX_SIZE 0x10000
+
+#define random_size() (random()%MAX_SIZE)
+#define random_ptr() (random()%N_PTRS)
+
+int test1(void);
+int test2(void);
+
+int main(int argc, char *argv[])
+{
+ return test1() + test2();
+}
+
+int test1(void)
+{
+ void **ptrs;
+ int i,j;
+ int size;
+ int ret = 0;
+
+ srandom(0x19730929);
+
+ ptrs = malloc(N_PTRS*sizeof(void *));
+
+ for(i=0; i<N_PTRS; i++){
+ if ((ptrs[i] = malloc(random_size())) == NULL) {
+ printf("malloc random failed! %i\n", i);
+ ++ret;
+ }
+ }
+ for(i=0; i<N_ALLOCS; i++){
+ j = random_ptr();
+ free(ptrs[j]);
+
+ size = random_size();
+ ptrs[j] = malloc(size);
+ if (!ptrs[j]) {
+ printf("malloc failed! %d\n", i);
+ ++ret;
+ }
+ memset(ptrs[j],0,size);
+ }
+ for(i=0; i<N_PTRS; i++){
+ free(ptrs[i]);
+ }
+
+ return ret;
+}
+
+int test2(void)
+{
+ void *ptr = NULL;
+ int ret = 0;
+
+ ptr = realloc(ptr,100);
+ if (!ptr) {
+ printf("couldn't realloc() a NULL pointer\n");
+ ++ret;
+ } else {
+ free(ptr);
+ }
+
+ ptr = malloc(100);
+ ptr = realloc(ptr, 0);
+ if (ptr) {
+ printf("realloc(,0) failed\n");
+ ++ret;
+ free(ptr);
+ }
+
+ return ret;
+}
+
diff --git a/test/malloc/mallocbug.c b/test/malloc/mallocbug.c
new file mode 100644
index 0000000..84a6387
--- /dev/null
+++ b/test/malloc/mallocbug.c
@@ -0,0 +1,67 @@
+/* Reproduce a GNU malloc bug. */
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+
+#define size_t unsigned int
+
+int
+main (int argc, char *argv[])
+{
+ char *dummy0;
+ char *dummy1;
+ char *fill_info_table1;
+ char *over_top;
+ size_t over_top_size = 0x3000;
+ char *over_top_dup;
+ size_t over_top_dup_size = 0x7000;
+ char *x;
+ size_t i;
+
+ /* Here's what memory is supposed to look like (hex):
+ size contents
+ 3000 original_info_table, later fill_info_table1
+ 3fa000 dummy0
+ 3fa000 dummy1
+ 6000 info_table_2
+ 3000 over_top
+
+ */
+ /* mem: original_info_table */
+ dummy0 = malloc (0x3fa000);
+ /* mem: original_info_table, dummy0 */
+ dummy1 = malloc (0x3fa000);
+ /* mem: free, dummy0, dummy1, info_table_2 */
+ fill_info_table1 = malloc (0x3000);
+ /* mem: fill_info_table1, dummy0, dummy1, info_table_2 */
+
+ x = malloc (0x1000);
+ free (x);
+ /* mem: fill_info_table1, dummy0, dummy1, info_table_2, freexx */
+
+ /* This is what loses; info_table_2 and freexx get combined unbeknownst
+ to mmalloc, and mmalloc puts over_top in a section of memory which
+ is on the free list as part of another block (where info_table_2 had
+ been). */
+ over_top = malloc (over_top_size);
+ over_top_dup = malloc (over_top_dup_size);
+ memset (over_top, 0, over_top_size);
+ memset (over_top_dup, 1, over_top_dup_size);
+
+ for (i = 0; i < over_top_size; ++i)
+ if (over_top[i] != 0)
+ {
+ printf ("FAIL: malloc expands info table\n");
+ return 0;
+ }
+
+ for (i = 0; i < over_top_dup_size; ++i)
+ if (over_top_dup[i] != 1)
+ {
+ printf ("FAIL: malloc expands info table\n");
+ return 0;
+ }
+
+ printf ("PASS: malloc expands info table\n");
+ return 0;
+}
diff --git a/test/malloc/realloc-can-shrink.c b/test/malloc/realloc-can-shrink.c
new file mode 100644
index 0000000..33249db
--- /dev/null
+++ b/test/malloc/realloc-can-shrink.c
@@ -0,0 +1,17 @@
+/* make sure that realloc() can properly shrink buffers */
+
+#include <stdlib.h>
+
+#define LARGE_BUFFER (1 << 20) /* idea is to span a lot of pages */
+
+int main(int argc, char *argv[])
+{
+ int count = 20;
+ char *ptr = NULL;
+ while (count--) {
+ ptr = realloc(ptr, LARGE_BUFFER);
+ ptr = realloc(ptr, 1);
+ }
+ free(ptr);
+ return 0;
+}
diff --git a/test/malloc/realloc0.c b/test/malloc/realloc0.c
new file mode 100644
index 0000000..62ae39d
--- /dev/null
+++ b/test/malloc/realloc0.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ void *ptr = NULL;
+ ptr = realloc(ptr, 0);
+ printf("realloc(NULL, 0) -- pointer = %p\n", ptr);
+
+ ptr = malloc(0);
+ printf("malloc(0) -- pointer = %p\n", ptr);
+ return 0;
+}
diff --git a/test/malloc/testmalloc.c b/test/malloc/testmalloc.c
new file mode 100644
index 0000000..42707d2
--- /dev/null
+++ b/test/malloc/testmalloc.c
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+struct list {
+ struct list *next;
+};
+
+int main(void)
+{
+ int z=999;
+ int *y=&z;
+ int *x=NULL;
+ struct list *save;
+ struct list *lp;
+ int i;
+
+
+ printf("pointer to x is %p\n", x);
+ printf("pointer to y is %p\n", y);
+ x=malloc(sizeof(int)*2000);
+ printf("pointer to x is %p\n", x);
+ y=malloc(sizeof(int)*100);
+ printf("pointer to y is %p\n", y);
+ free(x);
+ free(y);
+ printf("about to free(0)\n");
+ free(0);
+
+ x=malloc(13);
+ printf("x = %p\n", x);
+ memcpy(x, "Small string", 13);
+ printf("0x%p test string1: %s\n", x, (char *)x);
+ y = realloc(x, 36);
+ printf("0x%p test string1: %s\n", y, (char *)y);
+ memcpy(y, "********** Larger string **********", 36);
+ printf("0x%p test string2: %s\n", y, (char *)y);
+ free(y);
+
+
+ printf("Allocate 100 nodes 500 bytes each\n");
+ save = 0;
+ for (i=0; i<100; i++) {
+ lp = malloc(500);
+ if (lp == 0) {
+ printf("loop 1: malloc returned 0\n");
+ goto Failed;
+ }
+ lp->next = save;
+ save = lp;
+ }
+
+ printf("freeing 100 nodes\n");
+ while (save) {
+ lp = save;
+ save = save->next;
+ free(lp);
+ }
+
+ printf("try realloc 100 times \n");
+ lp = 0;
+ for (i=1; i<=100; i++) {
+ lp = realloc(lp, i*200);
+ if (lp == 0) {
+ printf("loop 3: realloc returned 0\n");
+ goto Failed;
+ }
+ }
+ {
+ void *unused_ret = realloc(lp, 0);
+ (void) unused_ret;
+ }
+
+ printf("Allocate another 100 nodes 600 bytes each\n");
+ save = 0;
+ for (i=0; i<100; i++) {
+ lp = malloc(600);
+ if (lp == 0) {
+ printf("loop 2: malloc returned 0\n");
+ goto Failed;
+ }
+ lp->next = save;
+ save = lp;
+ }
+
+ printf("freeing 100 nodes\n");
+ while (save) {
+ lp = save;
+ save = save->next;
+ free(lp);
+ }
+
+
+ printf("alloc test PASSED\n");
+ exit(0);
+
+Failed:
+ printf("!!!!!!!!!!!! alloc test FAILED. !!!!!!!!!!!!!!!\n");
+ exit(1);
+}
diff --git a/test/malloc/time_malloc.c b/test/malloc/time_malloc.c
new file mode 100644
index 0000000..0b62665
--- /dev/null
+++ b/test/malloc/time_malloc.c
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#define REPS (100000)
+int sizes[] = {
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50,
+ 100000, 1024, 42000, 350, 100, 80, 3 ,3,3,3,3,3,3,3,3,3,3,3,3,50
+};
+#define NUM (sizeof sizes / sizeof sizes[0])
+int main ()
+{
+ int i, j;
+ void *allocs[NUM];
+ for (i = 0; i < REPS; i++) {
+ for (j = 0; j < NUM; j++) {
+ allocs[j] = malloc(sizes[j]);
+ }
+ for (j = 0; j < NUM; j++) {
+ free(allocs[j]);
+ }
+ }
+ return 0;
+}
+
diff --git a/test/malloc/tst-asprintf.c b/test/malloc/tst-asprintf.c
new file mode 100644
index 0000000..d4c3f76
--- /dev/null
+++ b/test/malloc/tst-asprintf.c
@@ -0,0 +1,27 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <malloc.h>
+
+static void my_stats(void)
+{
+ malloc_stats();
+ fprintf(stderr, "\n");
+}
+
+int main(int argc, char *argv[])
+{
+ char *a, *b;
+
+ my_stats();
+ asprintf(&b, "asdsadasd %ssdf\n", "AAAA");
+ my_stats();
+ asprintf(&a, "asdsadasd %ssdf\n", "AAAA");
+ my_stats();
+ free(a);
+ free(b);
+ my_stats();
+
+ return 0;
+}
diff --git a/test/malloc/tst-calloc.c b/test/malloc/tst-calloc.c
new file mode 100644
index 0000000..b7b6d2b
--- /dev/null
+++ b/test/malloc/tst-calloc.c
@@ -0,0 +1,127 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>.
+
+ 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 <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static int errors = 0;
+
+/* Number of samples per size. */
+#define N 50000
+
+
+static void
+fixed_test (int size)
+{
+ char *ptrs[N];
+ int i;
+
+ for (i = 0; i < N; ++i)
+ {
+ int j;
+
+ ptrs[i] = (char *) calloc (1, size);
+
+ if (ptrs[i] == NULL)
+ break;
+
+ for (j = 0; j < size; ++j)
+ {
+ if (ptrs[i][j] != '\0') {
+ ++errors;
+ printf("byte not cleared (size %d, element %d, byte %d)",
+ size, i, j);
+ }
+ ptrs[i][j] = '\xff';
+ }
+ }
+
+ while (i-- > 0)
+ free (ptrs[i]);
+}
+
+
+static void
+random_test (void)
+{
+ char *ptrs[N];
+ int i;
+
+ for (i = 0; i < N; ++i)
+ {
+ int j;
+ int n = 1 + random () % 10;
+ int elem = 1 + random () % 100;
+ int size = n * elem;
+
+ ptrs[i] = (char *) calloc (n, elem);
+
+ if (ptrs[i] == NULL)
+ break;
+
+ for (j = 0; j < size; ++j)
+ {
+ if (ptrs[i][j] != '\0') {
+ ++errors;
+ printf("byte not cleared (size %d, element %d, byte %d)",
+ size, i, j);
+ }
+ ptrs[i][j] = '\xff';
+ }
+ }
+
+ while (i-- > 0)
+ free (ptrs[i]);
+}
+
+
+static void
+null_test (void)
+{
+ /* If the size is 0 the result is implementation defined. Just make
+ sure the program doesn't crash. */
+ calloc (0, 0);
+ calloc (0, UINT_MAX);
+ calloc (UINT_MAX, 0);
+ calloc (0, ~((size_t) 0));
+ calloc (~((size_t) 0), 0);
+}
+
+
+int
+main (void)
+{
+ /* We are allocating blocks with `calloc' and check whether every
+ block is completely cleared. We first try this for some fixed
+ times and then with random size. */
+ fixed_test (15);
+ fixed_test (5);
+ fixed_test (17);
+ fixed_test (6);
+ fixed_test (31);
+ fixed_test (96);
+
+ random_test ();
+
+ null_test ();
+
+ return errors != 0;
+}
diff --git a/test/malloc/tst-malloc.c b/test/malloc/tst-malloc.c
new file mode 100644
index 0000000..2d3bcce
--- /dev/null
+++ b/test/malloc/tst-malloc.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1999.
+
+ 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 <features.h>
+
+static int errors = 0;
+
+static void
+merror (const char *msg)
+{
+ ++errors;
+ printf ("Error: %s\n", msg);
+}
+
+int
+main (void)
+{
+ void *p;
+ int save;
+
+ errno = 0;
+
+ p = malloc (-1);
+ save = errno;
+
+ if (p != NULL)
+ merror ("malloc (-1) succeeded.");
+
+ if (p == NULL && save != ENOMEM)
+ merror ("errno is not set correctly");
+
+ p = malloc (10);
+ if (p == NULL)
+ merror ("malloc (10) failed.");
+
+ /* realloc (p, 0) == free (p). */
+ p = realloc (p, 0);
+ if (p != NULL)
+ merror ("realloc (p, 0) failed.");
+
+ p = malloc (0);
+#if !defined(__UCLIBC__) || defined(__MALLOC_GLIBC_COMPAT__)
+ if (p == NULL)
+#else
+ if (p != NULL)
+#endif
+ merror ("malloc (0) failed.");
+
+ p = realloc (p, 0);
+ if (p != NULL)
+ merror ("realloc (p, 0) failed.");
+
+ return errors != 0;
+}
diff --git a/test/malloc/tst-mallocfork.c b/test/malloc/tst-mallocfork.c
new file mode 100644
index 0000000..5bb1d76
--- /dev/null
+++ b/test/malloc/tst-mallocfork.c
@@ -0,0 +1,51 @@
+/* Derived from the test case in
+ http://sourceware.org/bugzilla/show_bug.cgi?id=838. */
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+static void
+sig_handler (int signum)
+{
+ pid_t child = vfork ();
+ if (child == 0)
+ exit (0);
+ TEMP_FAILURE_RETRY (waitpid (child, NULL, 0));
+}
+
+static int
+do_test (void)
+{
+ pid_t parent = getpid ();
+
+ struct sigaction action = { .sa_handler = sig_handler };
+ sigemptyset (&action.sa_mask);
+
+ malloc (sizeof (int));
+
+ if (sigaction (SIGALRM, &action, NULL) != 0)
+ {
+ puts ("sigaction failed");
+ return 1;
+ }
+
+ /* Create a child that sends the signal to be caught. */
+ pid_t child = vfork ();
+ if (child == 0)
+ {
+ if (kill (parent, SIGALRM) == -1)
+ perror ("kill");
+ exit (0);
+ }
+
+ TEMP_FAILURE_RETRY (waitpid (child, NULL, 0));
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/test/malloc/tst-mcheck.c b/test/malloc/tst-mcheck.c
new file mode 100644
index 0000000..9297d79
--- /dev/null
+++ b/test/malloc/tst-mcheck.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
+
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <features.h>
+
+static int errors = 0;
+
+static void
+merror (const char *msg)
+{
+ ++errors;
+ printf ("Error: %s\n", msg);
+}
+
+int
+main (void)
+{
+ void *p, *q;
+
+ errno = 0;
+
+ p = malloc (-1);
+
+ if (p != NULL)
+ merror ("malloc (-1) succeeded.");
+ else if (errno != ENOMEM)
+ merror ("errno is not set correctly.");
+
+ p = malloc (10);
+ if (p == NULL)
+ merror ("malloc (10) failed.");
+
+ p = realloc (p, 0);
+ if (p != NULL)
+ merror ("realloc (p, 0) failed.");
+
+ p = malloc (0);
+#if !defined(__UCLIBC__) || defined(__MALLOC_GLIBC_COMPAT__)
+ if (p == NULL)
+#else
+ if (p != NULL)
+#endif
+ merror ("malloc (0) failed.");
+
+ p = realloc (p, 0);
+ if (p != NULL)
+ merror ("realloc (p, 0) failed.");
+
+ q = malloc (256);
+ if (q == NULL)
+ merror ("malloc (256) failed.");
+
+ p = malloc (512);
+ if (p == NULL)
+ merror ("malloc (512) failed.");
+
+ if (realloc (p, -256) != NULL)
+ merror ("realloc (p, -256) succeeded.");
+ else if (errno != ENOMEM)
+ merror ("errno is not set correctly.");
+
+ free (p);
+
+ p = malloc (512);
+ if (p == NULL)
+ merror ("malloc (512) failed.");
+
+ if (realloc (p, -1) != NULL)
+ merror ("realloc (p, -1) succeeded.");
+ else if (errno != ENOMEM)
+ merror ("errno is not set correctly.");
+
+ free (p);
+ free (q);
+
+ return errors != 0;
+}
diff --git a/test/malloc/tst-obstack.c b/test/malloc/tst-obstack.c
new file mode 100644
index 0000000..1841946
--- /dev/null
+++ b/test/malloc/tst-obstack.c
@@ -0,0 +1,104 @@
+/* Test case by Alexandre Duret-Lutz <duret_g@epita.fr>.
+ * test_obstack_printf() added by Anthony G. Basile <blueness.gentoo.org>.
+ */
+
+#include <features.h>
+#include <obstack.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define obstack_chunk_alloc verbose_malloc
+#define obstack_chunk_free verbose_free
+#define ALIGN_BOUNDARY 64
+#define ALIGN_MASK (ALIGN_BOUNDARY - 1)
+#define OBJECT_SIZE 1000
+
+static void *
+verbose_malloc (size_t size)
+{
+ void *buf = malloc (size);
+ printf ("malloc (%zu) => %p\n", size, buf);
+ return buf;
+}
+
+static void
+verbose_free (void *buf)
+{
+ free (buf);
+ printf ("free (%p)\n", buf);
+}
+
+int
+test_obstack_alloc (void)
+{
+ int result = 0;
+ int align = 2;
+
+ while (align <= 64)
+ {
+ struct obstack obs;
+ int i;
+ int align_mask = align - 1;
+
+ printf ("\n Alignment mask: %d\n", align_mask);
+
+ obstack_init (&obs);
+ obstack_alignment_mask (&obs) = align_mask;
+ /* finish an empty object to take alignment into account */
+ obstack_finish (&obs);
+
+ /* let's allocate some objects and print their addresses */
+ for (i = 15; i > 0; --i)
+ {
+ void *obj = obstack_alloc (&obs, OBJECT_SIZE);
+
+ printf ("obstack_alloc (%u) => %p \t%s\n", OBJECT_SIZE, obj,
+ ((uintptr_t) obj & align_mask) ? "(not aligned)" : "");
+ result |= ((uintptr_t) obj & align_mask) != 0;
+ }
+
+ /* clean up */
+ obstack_free (&obs, 0);
+
+ align <<= 1;
+ }
+
+ return result;
+}
+
+int
+test_obstack_printf (void)
+{
+ int result = 0;
+ int n;
+ char *s;
+ struct obstack ob;
+
+ obstack_init (&ob);
+
+ n = obstack_printf (&ob, "%s%d%c", "testing 1 ... 2 ... ", 3, '\n');
+ result |= (n != 22);
+ printf("obstack_printf => %d\n", n);
+
+ n = obstack_printf (&ob, "%s%d%c", "testing 3 ... 2 ... ", 1, '\0');
+ result |= (n != 22);
+ printf("obstack_printf => %d\n", n);
+
+ s = obstack_finish (&ob);
+ printf("obstack_printf => %s\n", s);
+ obstack_free (&ob, NULL);
+
+ return result;
+}
+
+int
+main (void)
+{
+ int result = 0;
+
+ result |= test_obstack_alloc();
+ result |= test_obstack_printf();
+
+ return result;
+}
diff --git a/test/malloc/tst-valloc.c b/test/malloc/tst-valloc.c
new file mode 100644
index 0000000..643a0dd
--- /dev/null
+++ b/test/malloc/tst-valloc.c
@@ -0,0 +1,23 @@
+/* Test case by Stephen Tweedie <sct@redhat.com>. */
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (void)
+{
+ char *p;
+ int pagesize = getpagesize ();
+ int i;
+
+ p = valloc (pagesize);
+ i = (long int) p;
+
+ if ((i & (pagesize-1)) != 0)
+ {
+ fprintf (stderr, "Alignment problem: valloc returns %p\n", p);
+ exit (1);
+ }
+
+ return 0;
+}